Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.6-rc5 296 lines 8.4 kB view raw
1/* 2 * TX4939 internal RTC driver 3 * Based on RBTX49xx patch from CELF patch archive. 4 * 5 * This file is subject to the terms and conditions of the GNU General Public 6 * License. See the file "COPYING" in the main directory of this archive 7 * for more details. 8 * 9 * (C) Copyright TOSHIBA CORPORATION 2005-2007 10 */ 11#include <linux/rtc.h> 12#include <linux/platform_device.h> 13#include <linux/interrupt.h> 14#include <linux/module.h> 15#include <linux/io.h> 16#include <linux/gfp.h> 17#include <asm/txx9/tx4939.h> 18 19struct tx4939rtc_plat_data { 20 struct rtc_device *rtc; 21 struct tx4939_rtc_reg __iomem *rtcreg; 22 spinlock_t lock; 23}; 24 25static struct tx4939rtc_plat_data *get_tx4939rtc_plat_data(struct device *dev) 26{ 27 return platform_get_drvdata(to_platform_device(dev)); 28} 29 30static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd) 31{ 32 int i = 0; 33 34 __raw_writel(cmd, &rtcreg->ctl); 35 /* This might take 30us (next 32.768KHz clock) */ 36 while (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_BUSY) { 37 /* timeout on approx. 100us (@ GBUS200MHz) */ 38 if (i++ > 200 * 100) 39 return -EBUSY; 40 cpu_relax(); 41 } 42 return 0; 43} 44 45static int tx4939_rtc_set_mmss(struct device *dev, unsigned long secs) 46{ 47 struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 48 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 49 int i, ret; 50 unsigned char buf[6]; 51 52 buf[0] = 0; 53 buf[1] = 0; 54 buf[2] = secs; 55 buf[3] = secs >> 8; 56 buf[4] = secs >> 16; 57 buf[5] = secs >> 24; 58 spin_lock_irq(&pdata->lock); 59 __raw_writel(0, &rtcreg->adr); 60 for (i = 0; i < 6; i++) 61 __raw_writel(buf[i], &rtcreg->dat); 62 ret = tx4939_rtc_cmd(rtcreg, 63 TX4939_RTCCTL_COMMAND_SETTIME | 64 (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); 65 spin_unlock_irq(&pdata->lock); 66 return ret; 67} 68 69static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm) 70{ 71 struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 72 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 73 int i, ret; 74 unsigned long sec; 75 unsigned char buf[6]; 76 77 spin_lock_irq(&pdata->lock); 78 ret = tx4939_rtc_cmd(rtcreg, 79 TX4939_RTCCTL_COMMAND_GETTIME | 80 (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); 81 if (ret) { 82 spin_unlock_irq(&pdata->lock); 83 return ret; 84 } 85 __raw_writel(2, &rtcreg->adr); 86 for (i = 2; i < 6; i++) 87 buf[i] = __raw_readl(&rtcreg->dat); 88 spin_unlock_irq(&pdata->lock); 89 sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; 90 rtc_time_to_tm(sec, tm); 91 return rtc_valid_tm(tm); 92} 93 94static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 95{ 96 struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 97 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 98 int i, ret; 99 unsigned long sec; 100 unsigned char buf[6]; 101 102 if (alrm->time.tm_sec < 0 || 103 alrm->time.tm_min < 0 || 104 alrm->time.tm_hour < 0 || 105 alrm->time.tm_mday < 0 || 106 alrm->time.tm_mon < 0 || 107 alrm->time.tm_year < 0) 108 return -EINVAL; 109 rtc_tm_to_time(&alrm->time, &sec); 110 buf[0] = 0; 111 buf[1] = 0; 112 buf[2] = sec; 113 buf[3] = sec >> 8; 114 buf[4] = sec >> 16; 115 buf[5] = sec >> 24; 116 spin_lock_irq(&pdata->lock); 117 __raw_writel(0, &rtcreg->adr); 118 for (i = 0; i < 6; i++) 119 __raw_writel(buf[i], &rtcreg->dat); 120 ret = tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_SETALARM | 121 (alrm->enabled ? TX4939_RTCCTL_ALME : 0)); 122 spin_unlock_irq(&pdata->lock); 123 return ret; 124} 125 126static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 127{ 128 struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 129 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 130 int i, ret; 131 unsigned long sec; 132 unsigned char buf[6]; 133 u32 ctl; 134 135 spin_lock_irq(&pdata->lock); 136 ret = tx4939_rtc_cmd(rtcreg, 137 TX4939_RTCCTL_COMMAND_GETALARM | 138 (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); 139 if (ret) { 140 spin_unlock_irq(&pdata->lock); 141 return ret; 142 } 143 __raw_writel(2, &rtcreg->adr); 144 for (i = 2; i < 6; i++) 145 buf[i] = __raw_readl(&rtcreg->dat); 146 ctl = __raw_readl(&rtcreg->ctl); 147 alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0; 148 alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0; 149 spin_unlock_irq(&pdata->lock); 150 sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; 151 rtc_time_to_tm(sec, &alrm->time); 152 return rtc_valid_tm(&alrm->time); 153} 154 155static int tx4939_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 156{ 157 struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 158 159 spin_lock_irq(&pdata->lock); 160 tx4939_rtc_cmd(pdata->rtcreg, 161 TX4939_RTCCTL_COMMAND_NOP | 162 (enabled ? TX4939_RTCCTL_ALME : 0)); 163 spin_unlock_irq(&pdata->lock); 164 return 0; 165} 166 167static irqreturn_t tx4939_rtc_interrupt(int irq, void *dev_id) 168{ 169 struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev_id); 170 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 171 unsigned long events = RTC_IRQF; 172 173 spin_lock(&pdata->lock); 174 if (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALMD) { 175 events |= RTC_AF; 176 tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_NOP); 177 } 178 spin_unlock(&pdata->lock); 179 rtc_update_irq(pdata->rtc, 1, events); 180 181 return IRQ_HANDLED; 182} 183 184static const struct rtc_class_ops tx4939_rtc_ops = { 185 .read_time = tx4939_rtc_read_time, 186 .read_alarm = tx4939_rtc_read_alarm, 187 .set_alarm = tx4939_rtc_set_alarm, 188 .set_mmss = tx4939_rtc_set_mmss, 189 .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, 190}; 191 192static ssize_t tx4939_rtc_nvram_read(struct file *filp, struct kobject *kobj, 193 struct bin_attribute *bin_attr, 194 char *buf, loff_t pos, size_t size) 195{ 196 struct device *dev = container_of(kobj, struct device, kobj); 197 struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 198 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 199 ssize_t count; 200 201 spin_lock_irq(&pdata->lock); 202 for (count = 0; count < size; count++) { 203 __raw_writel(pos++, &rtcreg->adr); 204 *buf++ = __raw_readl(&rtcreg->dat); 205 } 206 spin_unlock_irq(&pdata->lock); 207 return count; 208} 209 210static ssize_t tx4939_rtc_nvram_write(struct file *filp, struct kobject *kobj, 211 struct bin_attribute *bin_attr, 212 char *buf, loff_t pos, size_t size) 213{ 214 struct device *dev = container_of(kobj, struct device, kobj); 215 struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); 216 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 217 ssize_t count; 218 219 spin_lock_irq(&pdata->lock); 220 for (count = 0; count < size; count++) { 221 __raw_writel(pos++, &rtcreg->adr); 222 __raw_writel(*buf++, &rtcreg->dat); 223 } 224 spin_unlock_irq(&pdata->lock); 225 return count; 226} 227 228static struct bin_attribute tx4939_rtc_nvram_attr = { 229 .attr = { 230 .name = "nvram", 231 .mode = S_IRUGO | S_IWUSR, 232 }, 233 .size = TX4939_RTC_REG_RAMSIZE, 234 .read = tx4939_rtc_nvram_read, 235 .write = tx4939_rtc_nvram_write, 236}; 237 238static int __init tx4939_rtc_probe(struct platform_device *pdev) 239{ 240 struct rtc_device *rtc; 241 struct tx4939rtc_plat_data *pdata; 242 struct resource *res; 243 int irq, ret; 244 245 irq = platform_get_irq(pdev, 0); 246 if (irq < 0) 247 return -ENODEV; 248 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 249 if (!pdata) 250 return -ENOMEM; 251 platform_set_drvdata(pdev, pdata); 252 253 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 254 pdata->rtcreg = devm_ioremap_resource(&pdev->dev, res); 255 if (IS_ERR(pdata->rtcreg)) 256 return PTR_ERR(pdata->rtcreg); 257 258 spin_lock_init(&pdata->lock); 259 tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); 260 if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt, 261 0, pdev->name, &pdev->dev) < 0) 262 return -EBUSY; 263 rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 264 &tx4939_rtc_ops, THIS_MODULE); 265 if (IS_ERR(rtc)) 266 return PTR_ERR(rtc); 267 pdata->rtc = rtc; 268 ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); 269 270 return ret; 271} 272 273static int __exit tx4939_rtc_remove(struct platform_device *pdev) 274{ 275 struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev); 276 277 sysfs_remove_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); 278 spin_lock_irq(&pdata->lock); 279 tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); 280 spin_unlock_irq(&pdata->lock); 281 return 0; 282} 283 284static struct platform_driver tx4939_rtc_driver = { 285 .remove = __exit_p(tx4939_rtc_remove), 286 .driver = { 287 .name = "tx4939rtc", 288 }, 289}; 290 291module_platform_driver_probe(tx4939_rtc_driver, tx4939_rtc_probe); 292 293MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); 294MODULE_DESCRIPTION("TX4939 internal RTC driver"); 295MODULE_LICENSE("GPL"); 296MODULE_ALIAS("platform:tx4939rtc");