123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Texas Instruments K3 RTC driver
- *
- * Copyright (C) 2021-2022 Texas Instruments Incorporated - https://www.ti.com/
- */
- #include <linux/clk.h>
- #include <linux/delay.h>
- #include <linux/mod_devicetable.h>
- #include <linux/module.h>
- #include <linux/of_device.h>
- #include <linux/platform_device.h>
- #include <linux/sys_soc.h>
- #include <linux/property.h>
- #include <linux/regmap.h>
- #include <linux/rtc.h>
- /* Registers */
- #define REG_K3RTC_S_CNT_LSW 0x08
- #define REG_K3RTC_S_CNT_MSW 0x0c
- #define REG_K3RTC_COMP 0x10
- #define REG_K3RTC_ON_OFF_S_CNT_LSW 0x20
- #define REG_K3RTC_ON_OFF_S_CNT_MSW 0x24
- #define REG_K3RTC_SCRATCH0 0x30
- #define REG_K3RTC_SCRATCH7 0x4c
- #define REG_K3RTC_GENERAL_CTL 0x50
- #define REG_K3RTC_IRQSTATUS_RAW_SYS 0x54
- #define REG_K3RTC_IRQSTATUS_SYS 0x58
- #define REG_K3RTC_IRQENABLE_SET_SYS 0x5c
- #define REG_K3RTC_IRQENABLE_CLR_SYS 0x60
- #define REG_K3RTC_SYNCPEND 0x68
- #define REG_K3RTC_KICK0 0x70
- #define REG_K3RTC_KICK1 0x74
- /* Freeze when lsw is read and unfreeze when msw is read */
- #define K3RTC_CNT_FMODE_S_CNT_VALUE (0x2 << 24)
- /* Magic values for lock/unlock */
- #define K3RTC_KICK0_UNLOCK_VALUE 0x83e70b13
- #define K3RTC_KICK1_UNLOCK_VALUE 0x95a4f1e0
- /* Multiplier for ppb conversions */
- #define K3RTC_PPB_MULT (1000000000LL)
- /* Min and max values supported with 'offset' interface (swapped sign) */
- #define K3RTC_MIN_OFFSET (-277761)
- #define K3RTC_MAX_OFFSET (277778)
- static const struct regmap_config ti_k3_rtc_regmap_config = {
- .name = "peripheral-registers",
- .reg_bits = 32,
- .val_bits = 32,
- .reg_stride = 4,
- .max_register = REG_K3RTC_KICK1,
- };
- enum ti_k3_rtc_fields {
- K3RTC_KICK0,
- K3RTC_KICK1,
- K3RTC_S_CNT_LSW,
- K3RTC_S_CNT_MSW,
- K3RTC_O32K_OSC_DEP_EN,
- K3RTC_UNLOCK,
- K3RTC_CNT_FMODE,
- K3RTC_PEND,
- K3RTC_RELOAD_FROM_BBD,
- K3RTC_COMP,
- K3RTC_ALM_S_CNT_LSW,
- K3RTC_ALM_S_CNT_MSW,
- K3RTC_IRQ_STATUS_RAW,
- K3RTC_IRQ_STATUS,
- K3RTC_IRQ_ENABLE_SET,
- K3RTC_IRQ_ENABLE_CLR,
- K3RTC_IRQ_STATUS_ALT,
- K3RTC_IRQ_ENABLE_CLR_ALT,
- K3_RTC_MAX_FIELDS
- };
- static const struct reg_field ti_rtc_reg_fields[] = {
- [K3RTC_KICK0] = REG_FIELD(REG_K3RTC_KICK0, 0, 31),
- [K3RTC_KICK1] = REG_FIELD(REG_K3RTC_KICK1, 0, 31),
- [K3RTC_S_CNT_LSW] = REG_FIELD(REG_K3RTC_S_CNT_LSW, 0, 31),
- [K3RTC_S_CNT_MSW] = REG_FIELD(REG_K3RTC_S_CNT_MSW, 0, 15),
- [K3RTC_O32K_OSC_DEP_EN] = REG_FIELD(REG_K3RTC_GENERAL_CTL, 21, 21),
- [K3RTC_UNLOCK] = REG_FIELD(REG_K3RTC_GENERAL_CTL, 23, 23),
- [K3RTC_CNT_FMODE] = REG_FIELD(REG_K3RTC_GENERAL_CTL, 24, 25),
- [K3RTC_PEND] = REG_FIELD(REG_K3RTC_SYNCPEND, 0, 1),
- [K3RTC_RELOAD_FROM_BBD] = REG_FIELD(REG_K3RTC_SYNCPEND, 31, 31),
- [K3RTC_COMP] = REG_FIELD(REG_K3RTC_COMP, 0, 31),
- /* We use on to off as alarm trigger */
- [K3RTC_ALM_S_CNT_LSW] = REG_FIELD(REG_K3RTC_ON_OFF_S_CNT_LSW, 0, 31),
- [K3RTC_ALM_S_CNT_MSW] = REG_FIELD(REG_K3RTC_ON_OFF_S_CNT_MSW, 0, 15),
- [K3RTC_IRQ_STATUS_RAW] = REG_FIELD(REG_K3RTC_IRQSTATUS_RAW_SYS, 0, 0),
- [K3RTC_IRQ_STATUS] = REG_FIELD(REG_K3RTC_IRQSTATUS_SYS, 0, 0),
- [K3RTC_IRQ_ENABLE_SET] = REG_FIELD(REG_K3RTC_IRQENABLE_SET_SYS, 0, 0),
- [K3RTC_IRQ_ENABLE_CLR] = REG_FIELD(REG_K3RTC_IRQENABLE_CLR_SYS, 0, 0),
- /* Off to on is alternate */
- [K3RTC_IRQ_STATUS_ALT] = REG_FIELD(REG_K3RTC_IRQSTATUS_SYS, 1, 1),
- [K3RTC_IRQ_ENABLE_CLR_ALT] = REG_FIELD(REG_K3RTC_IRQENABLE_CLR_SYS, 1, 1),
- };
- /**
- * struct ti_k3_rtc - Private data for ti-k3-rtc
- * @irq: IRQ
- * @sync_timeout_us: data sync timeout period in uSec
- * @rate_32k: 32k clock rate in Hz
- * @rtc_dev: rtc device
- * @regmap: rtc mmio regmap
- * @r_fields: rtc register fields
- */
- struct ti_k3_rtc {
- unsigned int irq;
- u32 sync_timeout_us;
- unsigned long rate_32k;
- struct rtc_device *rtc_dev;
- struct regmap *regmap;
- struct regmap_field *r_fields[K3_RTC_MAX_FIELDS];
- };
- static int k3rtc_field_read(struct ti_k3_rtc *priv, enum ti_k3_rtc_fields f)
- {
- int ret;
- int val;
- ret = regmap_field_read(priv->r_fields[f], &val);
- /*
- * We shouldn't be seeing regmap fail on us for mmio reads
- * This is possible if clock context fails, but that isn't the case for us
- */
- if (WARN_ON_ONCE(ret))
- return ret;
- return val;
- }
- static void k3rtc_field_write(struct ti_k3_rtc *priv, enum ti_k3_rtc_fields f, u32 val)
- {
- regmap_field_write(priv->r_fields[f], val);
- }
- /**
- * k3rtc_fence - Ensure a register sync took place between the two domains
- * @priv: pointer to priv data
- *
- * Return: 0 if the sync took place, else returns -ETIMEDOUT
- */
- static int k3rtc_fence(struct ti_k3_rtc *priv)
- {
- int ret;
- ret = regmap_field_read_poll_timeout(priv->r_fields[K3RTC_PEND], ret,
- !ret, 2, priv->sync_timeout_us);
- return ret;
- }
- static inline int k3rtc_check_unlocked(struct ti_k3_rtc *priv)
- {
- int ret;
- ret = k3rtc_field_read(priv, K3RTC_UNLOCK);
- if (ret < 0)
- return ret;
- return (ret) ? 0 : 1;
- }
- static int k3rtc_unlock_rtc(struct ti_k3_rtc *priv)
- {
- int ret;
- ret = k3rtc_check_unlocked(priv);
- if (!ret)
- return ret;
- k3rtc_field_write(priv, K3RTC_KICK0, K3RTC_KICK0_UNLOCK_VALUE);
- k3rtc_field_write(priv, K3RTC_KICK1, K3RTC_KICK1_UNLOCK_VALUE);
- /* Skip fence since we are going to check the unlock bit as fence */
- ret = regmap_field_read_poll_timeout(priv->r_fields[K3RTC_UNLOCK], ret,
- ret, 2, priv->sync_timeout_us);
- return ret;
- }
- /*
- * This is the list of SoCs affected by TI's i2327 errata causing the RTC
- * state-machine to break if not unlocked fast enough during boot. These
- * SoCs must have the bootloader unlock this device very early in the
- * boot-flow before we (Linux) can use this device.
- */
- static const struct soc_device_attribute has_erratum_i2327[] = {
- { .family = "AM62X", .revision = "SR1.0" },
- { /* sentinel */ }
- };
- static int k3rtc_configure(struct device *dev)
- {
- int ret;
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- /*
- * HWBUG: The compare state machine is broken if the RTC module
- * is NOT unlocked in under one second of boot - which is pretty long
- * time from the perspective of Linux driver (module load, u-boot
- * shell all can take much longer than this.
- *
- * In such occurrence, it is assumed that the RTC module is unusable
- */
- if (soc_device_match(has_erratum_i2327)) {
- ret = k3rtc_check_unlocked(priv);
- /* If there is an error OR if we are locked, return error */
- if (ret) {
- dev_err(dev,
- HW_ERR "Erratum i2327 unlock QUIRK! Cannot operate!!\n");
- return -EFAULT;
- }
- } else {
- /* May need to explicitly unlock first time */
- ret = k3rtc_unlock_rtc(priv);
- if (ret) {
- dev_err(dev, "Failed to unlock(%d)!\n", ret);
- return ret;
- }
- }
- /* Enable Shadow register sync on 32k clock boundary */
- k3rtc_field_write(priv, K3RTC_O32K_OSC_DEP_EN, 0x1);
- /*
- * Wait at least clock sync time before proceeding further programming.
- * This ensures that the 32k based sync is active.
- */
- usleep_range(priv->sync_timeout_us, priv->sync_timeout_us + 5);
- /* We need to ensure fence here to make sure sync here */
- ret = k3rtc_fence(priv);
- if (ret) {
- dev_err(dev,
- "Failed fence osc_dep enable(%d) - is 32k clk working?!\n", ret);
- return ret;
- }
- /*
- * FMODE setting: Reading lower seconds will freeze value on higher
- * seconds. This also implies that we must *ALWAYS* read lower seconds
- * prior to reading higher seconds
- */
- k3rtc_field_write(priv, K3RTC_CNT_FMODE, K3RTC_CNT_FMODE_S_CNT_VALUE);
- /* Clear any spurious IRQ sources if any */
- k3rtc_field_write(priv, K3RTC_IRQ_STATUS_ALT, 0x1);
- k3rtc_field_write(priv, K3RTC_IRQ_STATUS, 0x1);
- /* Disable all IRQs */
- k3rtc_field_write(priv, K3RTC_IRQ_ENABLE_CLR_ALT, 0x1);
- k3rtc_field_write(priv, K3RTC_IRQ_ENABLE_CLR, 0x1);
- /* And.. Let us Sync the writes in */
- return k3rtc_fence(priv);
- }
- static int ti_k3_rtc_read_time(struct device *dev, struct rtc_time *tm)
- {
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- u32 seconds_lo, seconds_hi;
- seconds_lo = k3rtc_field_read(priv, K3RTC_S_CNT_LSW);
- seconds_hi = k3rtc_field_read(priv, K3RTC_S_CNT_MSW);
- rtc_time64_to_tm((((time64_t)seconds_hi) << 32) | (time64_t)seconds_lo, tm);
- return 0;
- }
- static int ti_k3_rtc_set_time(struct device *dev, struct rtc_time *tm)
- {
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- time64_t seconds;
- seconds = rtc_tm_to_time64(tm);
- /*
- * Read operation on LSW will freeze the RTC, so to update
- * the time, we cannot use field operations. Just write since the
- * reserved bits are ignored.
- */
- regmap_write(priv->regmap, REG_K3RTC_S_CNT_LSW, seconds);
- regmap_write(priv->regmap, REG_K3RTC_S_CNT_MSW, seconds >> 32);
- return k3rtc_fence(priv);
- }
- static int ti_k3_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
- {
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- u32 reg;
- u32 offset = enabled ? K3RTC_IRQ_ENABLE_SET : K3RTC_IRQ_ENABLE_CLR;
- reg = k3rtc_field_read(priv, K3RTC_IRQ_ENABLE_SET);
- if ((enabled && reg) || (!enabled && !reg))
- return 0;
- k3rtc_field_write(priv, offset, 0x1);
- /*
- * Ensure the write sync is through - NOTE: it should be OK to have
- * ISR to fire as we are checking sync (which should be done in a 32k
- * cycle or so).
- */
- return k3rtc_fence(priv);
- }
- static int ti_k3_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
- {
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- u32 seconds_lo, seconds_hi;
- seconds_lo = k3rtc_field_read(priv, K3RTC_ALM_S_CNT_LSW);
- seconds_hi = k3rtc_field_read(priv, K3RTC_ALM_S_CNT_MSW);
- rtc_time64_to_tm((((time64_t)seconds_hi) << 32) | (time64_t)seconds_lo, &alarm->time);
- alarm->enabled = k3rtc_field_read(priv, K3RTC_IRQ_ENABLE_SET);
- return 0;
- }
- static int ti_k3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
- {
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- time64_t seconds;
- int ret;
- seconds = rtc_tm_to_time64(&alarm->time);
- k3rtc_field_write(priv, K3RTC_ALM_S_CNT_LSW, seconds);
- k3rtc_field_write(priv, K3RTC_ALM_S_CNT_MSW, (seconds >> 32));
- /* Make sure the alarm time is synced in */
- ret = k3rtc_fence(priv);
- if (ret) {
- dev_err(dev, "Failed to fence(%d)! Potential config issue?\n", ret);
- return ret;
- }
- /* Alarm IRQ enable will do a sync */
- return ti_k3_rtc_alarm_irq_enable(dev, alarm->enabled);
- }
- static int ti_k3_rtc_read_offset(struct device *dev, long *offset)
- {
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- u32 ticks_per_hr = priv->rate_32k * 3600;
- int comp;
- s64 tmp;
- comp = k3rtc_field_read(priv, K3RTC_COMP);
- /* Convert from RTC calibration register format to ppb format */
- tmp = comp * (s64)K3RTC_PPB_MULT;
- if (tmp < 0)
- tmp -= ticks_per_hr / 2LL;
- else
- tmp += ticks_per_hr / 2LL;
- tmp = div_s64(tmp, ticks_per_hr);
- /* Offset value operates in negative way, so swap sign */
- *offset = (long)-tmp;
- return 0;
- }
- static int ti_k3_rtc_set_offset(struct device *dev, long offset)
- {
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- u32 ticks_per_hr = priv->rate_32k * 3600;
- int comp;
- s64 tmp;
- /* Make sure offset value is within supported range */
- if (offset < K3RTC_MIN_OFFSET || offset > K3RTC_MAX_OFFSET)
- return -ERANGE;
- /* Convert from ppb format to RTC calibration register format */
- tmp = offset * (s64)ticks_per_hr;
- if (tmp < 0)
- tmp -= K3RTC_PPB_MULT / 2LL;
- else
- tmp += K3RTC_PPB_MULT / 2LL;
- tmp = div_s64(tmp, K3RTC_PPB_MULT);
- /* Offset value operates in negative way, so swap sign */
- comp = (int)-tmp;
- k3rtc_field_write(priv, K3RTC_COMP, comp);
- return k3rtc_fence(priv);
- }
- static irqreturn_t ti_k3_rtc_interrupt(s32 irq, void *dev_id)
- {
- struct device *dev = dev_id;
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- u32 reg;
- int ret;
- /*
- * IRQ assertion can be very fast, however, the IRQ Status clear
- * de-assert depends on 32k clock edge in the 32k domain
- * If we clear the status prior to the first 32k clock edge,
- * the status bit is cleared, but the IRQ stays re-asserted.
- *
- * To prevent this condition, we need to wait for clock sync time.
- * We can either do that by polling the 32k observability signal for
- * a toggle OR we could just sleep and let the processor do other
- * stuff.
- */
- usleep_range(priv->sync_timeout_us, priv->sync_timeout_us + 2);
- /* Lets make sure that this is a valid interrupt */
- reg = k3rtc_field_read(priv, K3RTC_IRQ_STATUS);
- if (!reg) {
- u32 raw = k3rtc_field_read(priv, K3RTC_IRQ_STATUS_RAW);
- dev_err(dev,
- HW_ERR
- "Erratum i2327/IRQ trig: status: 0x%08x / 0x%08x\n", reg, raw);
- return IRQ_NONE;
- }
- /*
- * Write 1 to clear status reg
- * We cannot use a field operation here due to a potential race between
- * 32k domain and vbus domain.
- */
- regmap_write(priv->regmap, REG_K3RTC_IRQSTATUS_SYS, 0x1);
- /* Sync the write in */
- ret = k3rtc_fence(priv);
- if (ret) {
- dev_err(dev, "Failed to fence irq status clr(%d)!\n", ret);
- return IRQ_NONE;
- }
- /*
- * Force the 32k status to be reloaded back in to ensure status is
- * reflected back correctly.
- */
- k3rtc_field_write(priv, K3RTC_RELOAD_FROM_BBD, 0x1);
- /* Ensure the write sync is through */
- ret = k3rtc_fence(priv);
- if (ret) {
- dev_err(dev, "Failed to fence reload from bbd(%d)!\n", ret);
- return IRQ_NONE;
- }
- /* Now we ensure that the status bit is cleared */
- ret = regmap_field_read_poll_timeout(priv->r_fields[K3RTC_IRQ_STATUS],
- ret, !ret, 2, priv->sync_timeout_us);
- if (ret) {
- dev_err(dev, "Time out waiting for status clear\n");
- return IRQ_NONE;
- }
- /* Notify RTC core on event */
- rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);
- return IRQ_HANDLED;
- }
- static const struct rtc_class_ops ti_k3_rtc_ops = {
- .read_time = ti_k3_rtc_read_time,
- .set_time = ti_k3_rtc_set_time,
- .read_alarm = ti_k3_rtc_read_alarm,
- .set_alarm = ti_k3_rtc_set_alarm,
- .read_offset = ti_k3_rtc_read_offset,
- .set_offset = ti_k3_rtc_set_offset,
- .alarm_irq_enable = ti_k3_rtc_alarm_irq_enable,
- };
- static int ti_k3_rtc_scratch_read(void *priv_data, unsigned int offset,
- void *val, size_t bytes)
- {
- struct ti_k3_rtc *priv = (struct ti_k3_rtc *)priv_data;
- return regmap_bulk_read(priv->regmap, REG_K3RTC_SCRATCH0 + offset, val, bytes / 4);
- }
- static int ti_k3_rtc_scratch_write(void *priv_data, unsigned int offset,
- void *val, size_t bytes)
- {
- struct ti_k3_rtc *priv = (struct ti_k3_rtc *)priv_data;
- int ret;
- ret = regmap_bulk_write(priv->regmap, REG_K3RTC_SCRATCH0 + offset, val, bytes / 4);
- if (ret)
- return ret;
- return k3rtc_fence(priv);
- }
- static struct nvmem_config ti_k3_rtc_nvmem_config = {
- .name = "ti_k3_rtc_scratch",
- .word_size = 4,
- .stride = 4,
- .size = REG_K3RTC_SCRATCH7 - REG_K3RTC_SCRATCH0 + 4,
- .reg_read = ti_k3_rtc_scratch_read,
- .reg_write = ti_k3_rtc_scratch_write,
- };
- static int k3rtc_get_32kclk(struct device *dev, struct ti_k3_rtc *priv)
- {
- struct clk *clk;
- clk = devm_clk_get_enabled(dev, "osc32k");
- if (IS_ERR(clk))
- return PTR_ERR(clk);
- priv->rate_32k = clk_get_rate(clk);
- /* Make sure we are exact 32k clock. Else, try to compensate delay */
- if (priv->rate_32k != 32768)
- dev_warn(dev, "Clock rate %ld is not 32768! Could misbehave!\n",
- priv->rate_32k);
- /*
- * Sync timeout should be two 32k clk sync cycles = ~61uS. We double
- * it to comprehend intermediate bus segment and cpu frequency
- * deltas
- */
- priv->sync_timeout_us = (u32)(DIV_ROUND_UP_ULL(1000000, priv->rate_32k) * 4);
- return 0;
- }
- static int k3rtc_get_vbusclk(struct device *dev, struct ti_k3_rtc *priv)
- {
- struct clk *clk;
- /* Note: VBUS isn't a context clock, it is needed for hardware operation */
- clk = devm_clk_get_enabled(dev, "vbus");
- if (IS_ERR(clk))
- return PTR_ERR(clk);
- return 0;
- }
- static int ti_k3_rtc_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
- struct ti_k3_rtc *priv;
- void __iomem *rtc_base;
- int ret;
- priv = devm_kzalloc(dev, sizeof(struct ti_k3_rtc), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
- rtc_base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(rtc_base))
- return PTR_ERR(rtc_base);
- priv->regmap = devm_regmap_init_mmio(dev, rtc_base, &ti_k3_rtc_regmap_config);
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
- ret = devm_regmap_field_bulk_alloc(dev, priv->regmap, priv->r_fields,
- ti_rtc_reg_fields, K3_RTC_MAX_FIELDS);
- if (ret)
- return ret;
- ret = k3rtc_get_32kclk(dev, priv);
- if (ret)
- return ret;
- ret = k3rtc_get_vbusclk(dev, priv);
- if (ret)
- return ret;
- ret = platform_get_irq(pdev, 0);
- if (ret < 0)
- return ret;
- priv->irq = (unsigned int)ret;
- priv->rtc_dev = devm_rtc_allocate_device(dev);
- if (IS_ERR(priv->rtc_dev))
- return PTR_ERR(priv->rtc_dev);
- priv->rtc_dev->ops = &ti_k3_rtc_ops;
- priv->rtc_dev->range_max = (1ULL << 48) - 1; /* 48Bit seconds */
- ti_k3_rtc_nvmem_config.priv = priv;
- ret = devm_request_threaded_irq(dev, priv->irq, NULL,
- ti_k3_rtc_interrupt,
- IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
- dev_name(dev), dev);
- if (ret) {
- dev_err(dev, "Could not request IRQ: %d\n", ret);
- return ret;
- }
- platform_set_drvdata(pdev, priv);
- ret = k3rtc_configure(dev);
- if (ret)
- return ret;
- if (device_property_present(dev, "wakeup-source"))
- device_init_wakeup(dev, true);
- else
- device_set_wakeup_capable(dev, true);
- ret = devm_rtc_register_device(priv->rtc_dev);
- if (ret)
- return ret;
- return devm_rtc_nvmem_register(priv->rtc_dev, &ti_k3_rtc_nvmem_config);
- }
- static const struct of_device_id ti_k3_rtc_of_match_table[] = {
- {.compatible = "ti,am62-rtc" },
- {}
- };
- MODULE_DEVICE_TABLE(of, ti_k3_rtc_of_match_table);
- static int __maybe_unused ti_k3_rtc_suspend(struct device *dev)
- {
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- if (device_may_wakeup(dev))
- return enable_irq_wake(priv->irq);
- return 0;
- }
- static int __maybe_unused ti_k3_rtc_resume(struct device *dev)
- {
- struct ti_k3_rtc *priv = dev_get_drvdata(dev);
- if (device_may_wakeup(dev))
- disable_irq_wake(priv->irq);
- return 0;
- }
- static SIMPLE_DEV_PM_OPS(ti_k3_rtc_pm_ops, ti_k3_rtc_suspend, ti_k3_rtc_resume);
- static struct platform_driver ti_k3_rtc_driver = {
- .probe = ti_k3_rtc_probe,
- .driver = {
- .name = "rtc-ti-k3",
- .of_match_table = ti_k3_rtc_of_match_table,
- .pm = &ti_k3_rtc_pm_ops,
- },
- };
- module_platform_driver(ti_k3_rtc_driver);
- MODULE_LICENSE("GPL");
- MODULE_DESCRIPTION("TI K3 RTC driver");
- MODULE_AUTHOR("Nishanth Menon");
|