10e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto/* 20e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto * TX4939 internal RTC driver 30e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto * Based on RBTX49xx patch from CELF patch archive. 40e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto * 50e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto * This file is subject to the terms and conditions of the GNU General Public 60e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto * License. See the file "COPYING" in the main directory of this archive 70e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto * for more details. 80e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto * 90e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto * (C) Copyright TOSHIBA CORPORATION 2005-2007 100e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto */ 110e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto#include <linux/rtc.h> 120e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto#include <linux/platform_device.h> 130e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto#include <linux/interrupt.h> 142113852b239ed4a93d04135372162252f9342bb6Paul Gortmaker#include <linux/module.h> 150e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto#include <linux/io.h> 165a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h> 170e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto#include <asm/txx9/tx4939.h> 180e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 190e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostruct tx4939rtc_plat_data { 200e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct rtc_device *rtc; 210e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939_rtc_reg __iomem *rtcreg; 22af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spinlock_t lock; 230e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto}; 240e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 250e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic struct tx4939rtc_plat_data *get_tx4939rtc_plat_data(struct device *dev) 260e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 270e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return platform_get_drvdata(to_platform_device(dev)); 280e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 290e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 300e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd) 310e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 320e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto int i = 0; 330e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 340e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto __raw_writel(cmd, &rtcreg->ctl); 350e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto /* This might take 30us (next 32.768KHz clock) */ 360e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto while (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_BUSY) { 370e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto /* timeout on approx. 100us (@ GBUS200MHz) */ 380e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (i++ > 200 * 100) 390e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return -EBUSY; 400e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto cpu_relax(); 410e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto } 420e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return 0; 430e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 440e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 450e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic int tx4939_rtc_set_mmss(struct device *dev, unsigned long secs) 460e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 470e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 480e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 490e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto int i, ret; 500e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto unsigned char buf[6]; 510e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 520e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[0] = 0; 530e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[1] = 0; 540e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[2] = secs; 550e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[3] = secs >> 8; 560e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[4] = secs >> 16; 570e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[5] = secs >> 24; 58af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_lock_irq(&pdata->lock); 590e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto __raw_writel(0, &rtcreg->adr); 600e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto for (i = 0; i < 6; i++) 610e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto __raw_writel(buf[i], &rtcreg->dat); 620e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto ret = tx4939_rtc_cmd(rtcreg, 630e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto TX4939_RTCCTL_COMMAND_SETTIME | 640e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); 65af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock_irq(&pdata->lock); 660e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return ret; 670e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 680e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 690e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm) 700e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 710e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 720e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 730e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto int i, ret; 740e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto unsigned long sec; 750e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto unsigned char buf[6]; 760e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 77af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_lock_irq(&pdata->lock); 780e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto ret = tx4939_rtc_cmd(rtcreg, 790e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto TX4939_RTCCTL_COMMAND_GETTIME | 800e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); 810e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (ret) { 82af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock_irq(&pdata->lock); 830e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return ret; 840e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto } 850e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto __raw_writel(2, &rtcreg->adr); 860e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto for (i = 2; i < 6; i++) 870e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[i] = __raw_readl(&rtcreg->dat); 88af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock_irq(&pdata->lock); 890e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; 900e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto rtc_time_to_tm(sec, tm); 910e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return rtc_valid_tm(tm); 920e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 930e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 940e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 950e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 960e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 970e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 980e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto int i, ret; 990e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto unsigned long sec; 1000e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto unsigned char buf[6]; 1010e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 1020e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (alrm->time.tm_sec < 0 || 1030e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto alrm->time.tm_min < 0 || 1040e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto alrm->time.tm_hour < 0 || 1050e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto alrm->time.tm_mday < 0 || 1060e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto alrm->time.tm_mon < 0 || 1070e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto alrm->time.tm_year < 0) 1080e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return -EINVAL; 1090e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto rtc_tm_to_time(&alrm->time, &sec); 1100e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[0] = 0; 1110e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[1] = 0; 1120e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[2] = sec; 1130e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[3] = sec >> 8; 1140e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[4] = sec >> 16; 1150e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[5] = sec >> 24; 116af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_lock_irq(&pdata->lock); 1170e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto __raw_writel(0, &rtcreg->adr); 1180e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto for (i = 0; i < 6; i++) 1190e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto __raw_writel(buf[i], &rtcreg->dat); 1200e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto ret = tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_SETALARM | 1210e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto (alrm->enabled ? TX4939_RTCCTL_ALME : 0)); 122af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock_irq(&pdata->lock); 1230e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return ret; 1240e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 1250e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 1260e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 1270e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 1280e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 1290e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 1300e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto int i, ret; 1310e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto unsigned long sec; 1320e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto unsigned char buf[6]; 1330e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto u32 ctl; 1340e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 135af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_lock_irq(&pdata->lock); 1360e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto ret = tx4939_rtc_cmd(rtcreg, 1370e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto TX4939_RTCCTL_COMMAND_GETALARM | 1380e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); 1390e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (ret) { 140af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock_irq(&pdata->lock); 1410e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return ret; 1420e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto } 1430e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto __raw_writel(2, &rtcreg->adr); 1440e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto for (i = 2; i < 6; i++) 1450e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto buf[i] = __raw_readl(&rtcreg->dat); 1460e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto ctl = __raw_readl(&rtcreg->ctl); 1470e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0; 1480e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0; 149af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock_irq(&pdata->lock); 1500e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; 1510e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto rtc_time_to_tm(sec, &alrm->time); 1520e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return rtc_valid_tm(&alrm->time); 1530e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 1540e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 1550e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic int tx4939_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 1560e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 1570e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 1580e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 159af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_lock_irq(&pdata->lock); 1600e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto tx4939_rtc_cmd(pdata->rtcreg, 1610e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto TX4939_RTCCTL_COMMAND_NOP | 1620e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto (enabled ? TX4939_RTCCTL_ALME : 0)); 163af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock_irq(&pdata->lock); 1640e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return 0; 1650e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 1660e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 1670e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic irqreturn_t tx4939_rtc_interrupt(int irq, void *dev_id) 1680e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 1690e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev_id); 1700e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 1710e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto unsigned long events = RTC_IRQF; 1720e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 173af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_lock(&pdata->lock); 1740e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALMD) { 1750e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto events |= RTC_AF; 1760e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_NOP); 1770e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto } 178af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock(&pdata->lock); 179af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto if (likely(pdata->rtc)) 180af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto rtc_update_irq(pdata->rtc, 1, events); 1810e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return IRQ_HANDLED; 1820e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 1830e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 1840e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic const struct rtc_class_ops tx4939_rtc_ops = { 1850e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .read_time = tx4939_rtc_read_time, 1860e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .read_alarm = tx4939_rtc_read_alarm, 1870e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .set_alarm = tx4939_rtc_set_alarm, 1880e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .set_mmss = tx4939_rtc_set_mmss, 1890e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, 1900e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto}; 1910e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 1922c3c8bea608866d8bd9dcf92657d57fdcac011c5Chris Wrightstatic ssize_t tx4939_rtc_nvram_read(struct file *filp, struct kobject *kobj, 1930e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct bin_attribute *bin_attr, 1940e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto char *buf, loff_t pos, size_t size) 1950e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 1960e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct device *dev = container_of(kobj, struct device, kobj); 1970e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 1980e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 1990e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto ssize_t count; 2000e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 201af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_lock_irq(&pdata->lock); 2020e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE; 2030e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto count++, size--) { 2040e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto __raw_writel(pos++, &rtcreg->adr); 2050e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto *buf++ = __raw_readl(&rtcreg->dat); 2060e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto } 207af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock_irq(&pdata->lock); 2080e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return count; 2090e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 2100e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 2112c3c8bea608866d8bd9dcf92657d57fdcac011c5Chris Wrightstatic ssize_t tx4939_rtc_nvram_write(struct file *filp, struct kobject *kobj, 2120e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct bin_attribute *bin_attr, 2130e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto char *buf, loff_t pos, size_t size) 2140e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 2150e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct device *dev = container_of(kobj, struct device, kobj); 2160e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 2170e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 2180e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto ssize_t count; 2190e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 220af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_lock_irq(&pdata->lock); 2210e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE; 2220e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto count++, size--) { 2230e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto __raw_writel(pos++, &rtcreg->adr); 2240e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto __raw_writel(*buf++, &rtcreg->dat); 2250e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto } 226af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock_irq(&pdata->lock); 2270e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return count; 2280e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 2290e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 2300e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic struct bin_attribute tx4939_rtc_nvram_attr = { 2310e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .attr = { 2320e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .name = "nvram", 2330e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .mode = S_IRUGO | S_IWUSR, 2340e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto }, 2350e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .size = TX4939_RTC_REG_RAMSIZE, 2360e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .read = tx4939_rtc_nvram_read, 2370e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .write = tx4939_rtc_nvram_write, 2380e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto}; 2390e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 2400e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic int __init tx4939_rtc_probe(struct platform_device *pdev) 2410e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 2420e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct rtc_device *rtc; 2430e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939rtc_plat_data *pdata; 2440e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct resource *res; 2450e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto int irq, ret; 2460e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 2470e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2480e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (!res) 2490e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return -ENODEV; 2500e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto irq = platform_get_irq(pdev, 0); 2510e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (irq < 0) 2520e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return -ENODEV; 2530e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 2540e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (!pdata) 2550e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return -ENOMEM; 2560e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto platform_set_drvdata(pdev, pdata); 2570e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 2580e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (!devm_request_mem_region(&pdev->dev, res->start, 2590e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto resource_size(res), pdev->name)) 2600e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return -EBUSY; 2610e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto pdata->rtcreg = devm_ioremap(&pdev->dev, res->start, 2620e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto resource_size(res)); 2630e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (!pdata->rtcreg) 2640e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return -EBUSY; 2650e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 266af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_lock_init(&pdata->lock); 2670e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); 2680e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt, 2690a817f7f5d95e8dde1b1ef57bd7c0a1fa7118268Atsushi Nemoto IRQF_DISABLED, pdev->name, &pdev->dev) < 0) 2700e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return -EBUSY; 2710e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto rtc = rtc_device_register(pdev->name, &pdev->dev, 2720e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto &tx4939_rtc_ops, THIS_MODULE); 2730e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (IS_ERR(rtc)) 2740e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return PTR_ERR(rtc); 2750e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto pdata->rtc = rtc; 2760e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); 2770e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto if (ret) 2780e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto rtc_device_unregister(rtc); 2790e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return ret; 2800e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 2810e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 2820e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic int __exit tx4939_rtc_remove(struct platform_device *pdev) 2830e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 2840e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev); 2850e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 2860e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto sysfs_remove_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); 287af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto rtc_device_unregister(pdata->rtc); 288af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_lock_irq(&pdata->lock); 289af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); 290af69a180e0675ce95842adb519079204ee5647eaAtsushi Nemoto spin_unlock_irq(&pdata->lock); 2910e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return 0; 2920e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 2930e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 2940e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic struct platform_driver tx4939_rtc_driver = { 2950e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .remove = __exit_p(tx4939_rtc_remove), 2960e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .driver = { 2970e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .name = "tx4939rtc", 2980e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto .owner = THIS_MODULE, 2990e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto }, 3000e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto}; 3010e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 3020e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic int __init tx4939rtc_init(void) 3030e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 3040e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto return platform_driver_probe(&tx4939_rtc_driver, tx4939_rtc_probe); 3050e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 3060e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 3070e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotostatic void __exit tx4939rtc_exit(void) 3080e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto{ 3090e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto platform_driver_unregister(&tx4939_rtc_driver); 3100e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto} 3110e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 3120e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotomodule_init(tx4939rtc_init); 3130e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemotomodule_exit(tx4939rtc_exit); 3140e1492330cd2c95df2553335d7a77351021a938fAtsushi Nemoto 3150e1492330cd2c95df2553335d7a77351021a938fAtsushi NemotoMODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); 3160e1492330cd2c95df2553335d7a77351021a938fAtsushi NemotoMODULE_DESCRIPTION("TX4939 internal RTC driver"); 3170e1492330cd2c95df2553335d7a77351021a938fAtsushi NemotoMODULE_LICENSE("GPL"); 3180e1492330cd2c95df2553335d7a77351021a938fAtsushi NemotoMODULE_ALIAS("platform:tx4939rtc"); 319