public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Lee Jones <lee.jones@linaro.org>
To: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: Sangbeom Kim <sbkim73@samsung.com>,
	Alessandro Zummo <a.zummo@towertech.it>,
	Alexandre Belloni <alexandre.belloni@free-electrons.com>,
	linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org,
	rtc-linux@googlegroups.com, Alim Akhtar <alim.akhtar@samsung.com>,
	Yadwinder Singh Brar <yadi.brar01@gmail.com>
Subject: Re: [PATCH v2 3/3] rtc: s5m: Make register configuration per S2MPS device to remove exceptions
Date: Mon, 11 Jan 2016 09:42:36 +0000	[thread overview]
Message-ID: <20160111094236.GO14104@x1> (raw)
In-Reply-To: <1451450847-928-3-git-send-email-k.kozlowski@samsung.com>

On Wed, 30 Dec 2015, Krzysztof Kozlowski wrote:

> Before updating time and alarm the driver must set appropriate mask in
> UDR register. For that purpose the driver uses common register
> configuration and a lot of exceptions per device in the code. The
> exceptions are not obvious, for example except the change in the logic
> sometimes the fields are swapped (WUDR and AUDR between S2MPS14 and
> S2MPS15). This leads to quite complicated code.
> 
> Try to make it more obvious by:
> 1. Documenting the UDR masks for devices and operations.
> 2. Adding fields in register configuration structure for each operation
>    (read time, write time and alarm).
> 3. Splitting the configuration per S2MPS13, S2MPS14 and S2MPS15 thus
>    removing exceptions for them.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> 
> ---
> 
> Tested on S2MPS11 (Odroid XU4) and S2MPS13. Testing on S2MPS15 would be
> appreciated!
> 
> Changes since v1:
> 1. Fix value used in S2MPS15_RTC_AUDR_MASK, pointed by Yadwinder Singh
>    Brar.
> ---
>  drivers/rtc/rtc-s5m.c           | 110 +++++++++++++++++++++++++++-------------
>  include/linux/mfd/samsung/rtc.h |   2 +

Acked-by: Lee Jones <lee.jones@linaro.org>

>  2 files changed, 77 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c
> index 559db8f72117..7407d7394bb4 100644
> --- a/drivers/rtc/rtc-s5m.c
> +++ b/drivers/rtc/rtc-s5m.c
> @@ -38,7 +38,22 @@
>   */
>  #define UDR_READ_RETRY_CNT	5
>  
> -/* Registers used by the driver which are different between chipsets. */
> +/*
> + * Registers used by the driver which are different between chipsets.
> + *
> + * Operations like read time and write alarm/time require updating
> + * specific fields in UDR register. These fields usually are auto-cleared
> + * (with some exceptions).
> + *
> + * Table of operations per device:
> + *
> + * Device     | Write time | Read time | Write alarm
> + * =================================================
> + * S5M8767    | UDR + TIME |           | UDR
> + * S2MPS11/14 | WUDR       | RUDR      | WUDR + RUDR
> + * S2MPS13    | WUDR       | RUDR      | WUDR + AUDR
> + * S2MPS15    | WUDR       | RUDR      | AUDR
> + */
>  struct s5m_rtc_reg_config {
>  	/* Number of registers used for setting time/alarm0/alarm1 */
>  	unsigned int regs_count;
> @@ -58,8 +73,13 @@ struct s5m_rtc_reg_config {
>  	unsigned int udr_update;
>  	/* Auto-cleared mask in UDR field for writing time and alarm */
>  	unsigned int autoclear_udr_mask;
> -	/* Mask for UDR field in 'udr_update' register */
> -	unsigned int udr_mask;
> +	/*
> +	 * Masks in UDR field for time and alarm operations.
> +	 * The read time mask can be 0. Rest should not.
> +	 */
> +	unsigned int read_time_udr_mask;
> +	unsigned int write_time_udr_mask;
> +	unsigned int write_alarm_udr_mask;
>  };
>  
>  /* Register map for S5M8763 and S5M8767 */
> @@ -71,14 +91,44 @@ static const struct s5m_rtc_reg_config s5m_rtc_regs = {
>  	.alarm1			= S5M_ALARM1_SEC,
>  	.udr_update		= S5M_RTC_UDR_CON,
>  	.autoclear_udr_mask	= S5M_RTC_UDR_MASK,
> -	.udr_mask		= S5M_RTC_UDR_MASK,
> +	.read_time_udr_mask	= 0, /* Not needed */
> +	.write_time_udr_mask	= S5M_RTC_UDR_MASK | S5M_RTC_TIME_EN_MASK,
> +	.write_alarm_udr_mask	= S5M_RTC_UDR_MASK,
> +};
> +
> +/* Register map for S2MPS13 */
> +static const struct s5m_rtc_reg_config s2mps13_rtc_regs = {
> +	.regs_count		= 7,
> +	.time			= S2MPS_RTC_SEC,
> +	.ctrl			= S2MPS_RTC_CTRL,
> +	.alarm0			= S2MPS_ALARM0_SEC,
> +	.alarm1			= S2MPS_ALARM1_SEC,
> +	.udr_update		= S2MPS_RTC_UDR_CON,
> +	.autoclear_udr_mask	= S2MPS_RTC_WUDR_MASK,
> +	.read_time_udr_mask	= S2MPS_RTC_RUDR_MASK,
> +	.write_time_udr_mask	= S2MPS_RTC_WUDR_MASK,
> +	.write_alarm_udr_mask	= S2MPS_RTC_WUDR_MASK | S2MPS13_RTC_AUDR_MASK,
> +};
> +
> +/* Register map for S2MPS11/14 */
> +static const struct s5m_rtc_reg_config s2mps14_rtc_regs = {
> +	.regs_count		= 7,
> +	.time			= S2MPS_RTC_SEC,
> +	.ctrl			= S2MPS_RTC_CTRL,
> +	.alarm0			= S2MPS_ALARM0_SEC,
> +	.alarm1			= S2MPS_ALARM1_SEC,
> +	.udr_update		= S2MPS_RTC_UDR_CON,
> +	.autoclear_udr_mask	= S2MPS_RTC_WUDR_MASK,
> +	.read_time_udr_mask	= S2MPS_RTC_RUDR_MASK,
> +	.write_time_udr_mask	= S2MPS_RTC_WUDR_MASK,
> +	.write_alarm_udr_mask	= S2MPS_RTC_WUDR_MASK | S2MPS_RTC_RUDR_MASK,
>  };
>  
>  /*
> - * Register map for S2MPS14.
> - * It may be also suitable for S2MPS11 but this was not tested.
> + * Register map for S2MPS15 - in comparison to S2MPS14 the WUDR and AUDR bits
> + * are swapped.
>   */
> -static const struct s5m_rtc_reg_config s2mps_rtc_regs = {
> +static const struct s5m_rtc_reg_config s2mps15_rtc_regs = {
>  	.regs_count		= 7,
>  	.time			= S2MPS_RTC_SEC,
>  	.ctrl			= S2MPS_RTC_CTRL,
> @@ -86,7 +136,9 @@ static const struct s5m_rtc_reg_config s2mps_rtc_regs = {
>  	.alarm1			= S2MPS_ALARM1_SEC,
>  	.udr_update		= S2MPS_RTC_UDR_CON,
>  	.autoclear_udr_mask	= S2MPS_RTC_WUDR_MASK,
> -	.udr_mask		= S2MPS_RTC_WUDR_MASK,
> +	.read_time_udr_mask	= S2MPS_RTC_RUDR_MASK,
> +	.write_time_udr_mask	= S2MPS15_RTC_WUDR_MASK,
> +	.write_alarm_udr_mask	= S2MPS15_RTC_AUDR_MASK,
>  };
>  
>  struct s5m_rtc_info {
> @@ -223,21 +275,7 @@ static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
>  		return ret;
>  	}
>  
> -	switch (info->device_type) {
> -	case S5M8763X:
> -	case S5M8767X:
> -		data |= info->regs->udr_mask | S5M_RTC_TIME_EN_MASK;
> -	case S2MPS15X:
> -		/* As per UM, for write time register, set WUDR bit to high */
> -		data |= S2MPS15_RTC_WUDR_MASK;
> -		break;
> -	case S2MPS14X:
> -	case S2MPS13X:
> -		data |= info->regs->udr_mask;
> -		break;
> -	default:
> -		return -EINVAL;
> -	}
> +	data |= info->regs->write_time_udr_mask;
>  
>  	ret = regmap_write(info->regmap, info->regs->udr_update, data);
>  	if (ret < 0) {
> @@ -262,22 +300,16 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
>  		return ret;
>  	}
>  
> -	data |= info->regs->udr_mask;
> +	data |= info->regs->write_alarm_udr_mask;
>  	switch (info->device_type) {
>  	case S5M8763X:
>  	case S5M8767X:
>  		data &= ~S5M_RTC_TIME_EN_MASK;
>  		break;
>  	case S2MPS15X:
> -		/* As per UM, for write alarm, set A_UDR(bit[4]) to high
> -		 * udr_mask above sets bit[4]
> -		 */
> -		break;
>  	case S2MPS14X:
> -		data |= S2MPS_RTC_RUDR_MASK;
> -		break;
>  	case S2MPS13X:
> -		data |= S2MPS13_RTC_AUDR_MASK;
> +		/* No exceptions needed */
>  		break;
>  	default:
>  		return -EINVAL;
> @@ -338,11 +370,11 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
>  	u8 data[info->regs->regs_count];
>  	int ret;
>  
> -	if (info->device_type == S2MPS15X || info->device_type == S2MPS14X ||
> -			info->device_type == S2MPS13X) {
> +	if (info->regs->read_time_udr_mask) {
>  		ret = regmap_update_bits(info->regmap,
>  				info->regs->udr_update,
> -				S2MPS_RTC_RUDR_MASK, S2MPS_RTC_RUDR_MASK);
> +				info->regs->read_time_udr_mask,
> +				info->regs->read_time_udr_mask);
>  		if (ret) {
>  			dev_err(dev,
>  				"Failed to prepare registers for time reading: %d\n",
> @@ -709,10 +741,18 @@ static int s5m_rtc_probe(struct platform_device *pdev)
>  
>  	switch (platform_get_device_id(pdev)->driver_data) {
>  	case S2MPS15X:
> +		regmap_cfg = &s2mps14_rtc_regmap_config;
> +		info->regs = &s2mps15_rtc_regs;
> +		alarm_irq = S2MPS14_IRQ_RTCA0;
> +		break;
>  	case S2MPS14X:
> +		regmap_cfg = &s2mps14_rtc_regmap_config;
> +		info->regs = &s2mps14_rtc_regs;
> +		alarm_irq = S2MPS14_IRQ_RTCA0;
> +		break;
>  	case S2MPS13X:
>  		regmap_cfg = &s2mps14_rtc_regmap_config;
> -		info->regs = &s2mps_rtc_regs;
> +		info->regs = &s2mps13_rtc_regs;
>  		alarm_irq = S2MPS14_IRQ_RTCA0;
>  		break;
>  	case S5M8763X:
> diff --git a/include/linux/mfd/samsung/rtc.h b/include/linux/mfd/samsung/rtc.h
> index a65e4655d470..48c3c5be7eb1 100644
> --- a/include/linux/mfd/samsung/rtc.h
> +++ b/include/linux/mfd/samsung/rtc.h
> @@ -105,6 +105,8 @@ enum s2mps_rtc_reg {
>  #define S5M_RTC_UDR_MASK	(1 << S5M_RTC_UDR_SHIFT)
>  #define S2MPS_RTC_WUDR_SHIFT	4
>  #define S2MPS_RTC_WUDR_MASK	(1 << S2MPS_RTC_WUDR_SHIFT)
> +#define S2MPS15_RTC_AUDR_SHIFT	4
> +#define S2MPS15_RTC_AUDR_MASK	(1 << S2MPS15_RTC_AUDR_SHIFT)
>  #define S2MPS13_RTC_AUDR_SHIFT	1
>  #define S2MPS13_RTC_AUDR_MASK	(1 << S2MPS13_RTC_AUDR_SHIFT)
>  #define S2MPS15_RTC_WUDR_SHIFT	1

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

  parent reply	other threads:[~2016-01-11  9:42 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-30  4:47 [PATCH v2 1/3] rtc: s5m: Cleanup by removing useless 'rtc' prefix from fields Krzysztof Kozlowski
2015-12-30  4:47 ` [PATCH v2 2/3] rtc: s5m: Add separate field for storing auto-cleared mask in register config Krzysztof Kozlowski
2015-12-30 10:09   ` Alim Akhtar
2015-12-30  4:47 ` [PATCH v2 3/3] rtc: s5m: Make register configuration per S2MPS device to remove exceptions Krzysztof Kozlowski
2015-12-30 10:14   ` Alim Akhtar
2015-12-30 12:26     ` [rtc-linux] " Krzysztof Kozlowski
2016-01-11  9:42   ` Lee Jones [this message]
2015-12-30 10:06 ` [PATCH v2 1/3] rtc: s5m: Cleanup by removing useless 'rtc' prefix from fields Alim Akhtar
2016-01-04 17:08 ` Alexandre Belloni
2016-01-04 23:53   ` Krzysztof Kozlowski
2016-01-05  0:04     ` Krzysztof Kozlowski
2016-01-05  0:07       ` Alexandre Belloni
2016-01-11 19:25       ` Alexandre Belloni

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160111094236.GO14104@x1 \
    --to=lee.jones@linaro.org \
    --cc=a.zummo@towertech.it \
    --cc=alexandre.belloni@free-electrons.com \
    --cc=alim.akhtar@samsung.com \
    --cc=k.kozlowski@samsung.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=rtc-linux@googlegroups.com \
    --cc=sbkim73@samsung.com \
    --cc=yadi.brar01@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox