Commit b7270c69 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull RTC updates from Alexandre Belloni:
 "A great rework of the isl12022 driver makes up the bulk of the
  changes. There is also an important fix for CMOS and then the usual
  small fixes:

   - switch to devm_clk_get_enabled() where relevant

   - cmos: event handler registration fix

   - isl12022: code improvements"

* tag 'rtc-6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux:
  rtc: rv3028: Fix codestyle errors
  rtc: cmos: Fix event handler registration ordering issue
  rtc: k3: Use devm_clk_get_enabled() helper
  rtc: jz4740: Use devm_clk_get_enabled() helper
  rtc: mpfs: Use devm_clk_get_enabled() helper
  rtc: ds1685: Fix spelling of function name in comment block
  rtc: isl12022: switch to using regmap API
  rtc: isl12022: drop redundant write to HR register
  rtc: isl12022: use dev_set_drvdata() instead of i2c_set_clientdata()
  rtc: isl12022: use %ptR
  rtc: isl12022: simplify some expressions
  rtc: isl12022: drop a dev_info()
  rtc: isl12022: specify range_min and range_max
  rtc: isl12022: stop using deprecated devm_rtc_device_register()
  rtc: stmp3xxx: Add failure handling for stmp3xxx_wdt_register()
  rtc: mxc: Use devm_clk_get_enabled() helper
  rtc: gamecube: Always reset HW_SRNPROT after read
  rtc: k3: detect SoC to determine erratum fix
  rtc: k3: wait until the unlock field is not zero
  rtc: mpfs: Remove printing of stray CR
parents 4ce1b979 e5f12a39
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -423,6 +423,7 @@ config RTC_DRV_ISL1208

config RTC_DRV_ISL12022
	tristate "Intersil ISL12022"
	select REGMAP_I2C
	help
	  If you say yes here you get support for the
	  Intersil ISL12022 RTC chip.
+19 −10
Original line number Diff line number Diff line
@@ -1352,10 +1352,10 @@ static void cmos_check_acpi_rtc_status(struct device *dev,

static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
{
	cmos_wake_setup(&pnp->dev);
	int irq, ret;

	if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
		unsigned int irq = 0;
		irq = 0;
#ifdef CONFIG_X86
		/* Some machines contain a PNP entry for the RTC, but
		 * don't define the IRQ. It should always be safe to
@@ -1364,13 +1364,17 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
		if (nr_legacy_irqs())
			irq = RTC_IRQ;
#endif
		return cmos_do_probe(&pnp->dev,
				pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
	} else {
		return cmos_do_probe(&pnp->dev,
				pnp_get_resource(pnp, IORESOURCE_IO, 0),
				pnp_irq(pnp, 0));
		irq = pnp_irq(pnp, 0);
	}

	ret = cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
	if (ret)
		return ret;

	cmos_wake_setup(&pnp->dev);

	return 0;
}

static void cmos_pnp_remove(struct pnp_dev *pnp)
@@ -1454,10 +1458,9 @@ static inline void cmos_of_init(struct platform_device *pdev) {}
static int __init cmos_platform_probe(struct platform_device *pdev)
{
	struct resource *resource;
	int irq;
	int irq, ret;

	cmos_of_init(pdev);
	cmos_wake_setup(&pdev->dev);

	if (RTC_IOMAPPED)
		resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -1467,7 +1470,13 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
	if (irq < 0)
		irq = -1;

	return cmos_do_probe(&pdev->dev, resource, irq);
	ret = cmos_do_probe(&pdev->dev, resource, irq);
	if (ret)
		return ret;

	cmos_wake_setup(&pdev->dev);

	return 0;
}

static int cmos_platform_remove(struct platform_device *pdev)
+1 −1
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ ds1685_rtc_bin2bcd(struct ds1685_priv *rtc, u8 val, u8 bin_mask, u8 bcd_mask)
}

/**
 * s1685_rtc_check_mday - check validity of the day of month.
 * ds1685_rtc_check_mday - check validity of the day of month.
 * @rtc: pointer to the ds1685 rtc structure.
 * @mday: day of month.
 *
+5 −6
Original line number Diff line number Diff line
@@ -265,18 +265,17 @@ static int gamecube_rtc_read_offset_from_sram(struct priv *d)
	 * SRAM address as on previous consoles.
	 */
	ret = regmap_read(d->regmap, RTC_SRAM_BIAS, &d->rtc_bias);
	if (ret) {
		pr_err("failed to get the RTC bias\n");
		iounmap(hw_srnprot);
		return -1;
	}

	/* Reset SRAM access to how it was before, our job here is done. */
	if (old != 0x7bf)
		iowrite32be(old, hw_srnprot);

	iounmap(hw_srnprot);

	return 0;
	if (ret)
		pr_err("failed to get the RTC bias\n");

	return ret;
}

static const struct regmap_range rtc_rd_ranges[] = {
+40 −121
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>

/* ISL register offsets */
#define ISL12022_REG_SC		0x00
@@ -42,83 +43,32 @@ static struct i2c_driver isl12022_driver;

struct isl12022 {
	struct rtc_device *rtc;

	bool write_enabled;	/* true if write enable is set */
};


static int isl12022_read_regs(struct i2c_client *client, uint8_t reg,
			      uint8_t *data, size_t n)
{
	struct i2c_msg msgs[] = {
		{
			.addr	= client->addr,
			.flags	= 0,
			.len	= 1,
			.buf	= data
		},		/* setup read ptr */
		{
			.addr	= client->addr,
			.flags	= I2C_M_RD,
			.len	= n,
			.buf	= data
		}
	struct regmap *regmap;
};

	int ret;

	data[0] = reg;
	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
	if (ret != ARRAY_SIZE(msgs)) {
		dev_err(&client->dev, "%s: read error, ret=%d\n",
			__func__, ret);
		return -EIO;
	}

	return 0;
}


static int isl12022_write_reg(struct i2c_client *client,
			      uint8_t reg, uint8_t val)
{
	uint8_t data[2] = { reg, val };
	int err;

	err = i2c_master_send(client, data, sizeof(data));
	if (err != sizeof(data)) {
		dev_err(&client->dev,
			"%s: err=%d addr=%02x, data=%02x\n",
			__func__, err, data[0], data[1]);
		return -EIO;
	}

	return 0;
}


/*
 * In the routines that deal directly with the isl12022 hardware, we use
 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
 */
static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct isl12022 *isl12022 = dev_get_drvdata(dev);
	struct regmap *regmap = isl12022->regmap;
	uint8_t buf[ISL12022_REG_INT + 1];
	int ret;

	ret = isl12022_read_regs(client, ISL12022_REG_SC, buf, sizeof(buf));
	ret = regmap_bulk_read(regmap, ISL12022_REG_SC, buf, sizeof(buf));
	if (ret)
		return ret;

	if (buf[ISL12022_REG_SR] & (ISL12022_SR_LBAT85 | ISL12022_SR_LBAT75)) {
		dev_warn(&client->dev,
		dev_warn(dev,
			 "voltage dropped below %u%%, "
			 "date and time is not reliable.\n",
			 buf[ISL12022_REG_SR] & ISL12022_SR_LBAT85 ? 85 : 75);
	}

	dev_dbg(&client->dev,
	dev_dbg(dev,
		"%s: raw data is sec=%02x, min=%02x, hr=%02x, "
		"mday=%02x, mon=%02x, year=%02x, wday=%02x, "
		"sr=%02x, int=%02x",
@@ -141,65 +91,25 @@ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
	tm->tm_mon = bcd2bin(buf[ISL12022_REG_MO] & 0x1F) - 1;
	tm->tm_year = bcd2bin(buf[ISL12022_REG_YR]) + 100;

	dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
		"mday=%d, mon=%d, year=%d, wday=%d\n",
		__func__,
		tm->tm_sec, tm->tm_min, tm->tm_hour,
		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
	dev_dbg(dev, "%s: %ptR\n", __func__, tm);

	return 0;
}

static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct isl12022 *isl12022 = i2c_get_clientdata(client);
	size_t i;
	struct isl12022 *isl12022 = dev_get_drvdata(dev);
	struct regmap *regmap = isl12022->regmap;
	int ret;
	uint8_t buf[ISL12022_REG_DW + 1];

	dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
		"mday=%d, mon=%d, year=%d, wday=%d\n",
		__func__,
		tm->tm_sec, tm->tm_min, tm->tm_hour,
		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

	if (!isl12022->write_enabled) {

		ret = isl12022_read_regs(client, ISL12022_REG_INT, buf, 1);
		if (ret)
			return ret;

		/* Check if WRTC (write rtc enable) is set factory default is
		 * 0 (not set) */
		if (!(buf[0] & ISL12022_INT_WRTC)) {
			dev_info(&client->dev,
				 "init write enable and 24 hour format\n");

			/* Set the write enable bit. */
			ret = isl12022_write_reg(client,
						 ISL12022_REG_INT,
						 buf[0] | ISL12022_INT_WRTC);
			if (ret)
				return ret;

			/* Write to any RTC register to start RTC, we use the
			 * HR register, setting the MIL bit to use the 24 hour
			 * format. */
			ret = isl12022_read_regs(client, ISL12022_REG_HR,
						 buf, 1);
			if (ret)
				return ret;
	dev_dbg(dev, "%s: %ptR\n", __func__, tm);

			ret = isl12022_write_reg(client,
						 ISL12022_REG_HR,
						 buf[0] | ISL12022_HR_MIL);
	/* Ensure the write enable bit is set. */
	ret = regmap_update_bits(regmap, ISL12022_REG_INT,
				 ISL12022_INT_WRTC, ISL12022_INT_WRTC);
	if (ret)
		return ret;
		}

		isl12022->write_enabled = true;
	}

	/* hours, minutes and seconds */
	buf[ISL12022_REG_SC] = bin2bcd(tm->tm_sec);
@@ -216,15 +126,8 @@ static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)

	buf[ISL12022_REG_DW] = tm->tm_wday & 0x07;

	/* write register's data */
	for (i = 0; i < ARRAY_SIZE(buf); i++) {
		ret = isl12022_write_reg(client, ISL12022_REG_SC + i,
					 buf[ISL12022_REG_SC + i]);
		if (ret)
			return -EIO;
	}

	return 0;
	return regmap_bulk_write(isl12022->regmap, ISL12022_REG_SC,
				 buf, sizeof(buf));
}

static const struct rtc_class_ops isl12022_rtc_ops = {
@@ -232,6 +135,12 @@ static const struct rtc_class_ops isl12022_rtc_ops = {
	.set_time	= isl12022_rtc_set_time,
};

static const struct regmap_config regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.use_single_write = true,
};

static int isl12022_probe(struct i2c_client *client)
{
	struct isl12022 *isl12022;
@@ -243,13 +152,23 @@ static int isl12022_probe(struct i2c_client *client)
				GFP_KERNEL);
	if (!isl12022)
		return -ENOMEM;
	dev_set_drvdata(&client->dev, isl12022);

	isl12022->regmap = devm_regmap_init_i2c(client, &regmap_config);
	if (IS_ERR(isl12022->regmap)) {
		dev_err(&client->dev, "regmap allocation failed\n");
		return PTR_ERR(isl12022->regmap);
	}

	isl12022->rtc = devm_rtc_allocate_device(&client->dev);
	if (IS_ERR(isl12022->rtc))
		return PTR_ERR(isl12022->rtc);

	i2c_set_clientdata(client, isl12022);
	isl12022->rtc->ops = &isl12022_rtc_ops;
	isl12022->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
	isl12022->rtc->range_max = RTC_TIMESTAMP_END_2099;

	isl12022->rtc = devm_rtc_device_register(&client->dev,
					isl12022_driver.driver.name,
					&isl12022_rtc_ops, THIS_MODULE);
	return PTR_ERR_OR_ZERO(isl12022->rtc);
	return devm_rtc_register_device(isl12022->rtc);
}

#ifdef CONFIG_OF
Loading