static int s3c_rtc_probe(struct platform_device *pdev) { struct s3c_rtc *info = NULL; struct rtc_time rtc_tm; struct resource *res; int ret; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; /* find the IRQs */ info->irq_tick = platform_get_irq(pdev, 1); if (info->irq_tick < 0) { dev_err(&pdev->dev, "no irq for rtc tick\n"); return info->irq_tick; } info->dev = &pdev->dev; info->data = of_device_get_match_data(&pdev->dev); if (!info->data) { dev_err(&pdev->dev, "failed getting s3c_rtc_data\n"); return -EINVAL; } spin_lock_init(&info->pie_lock); spin_lock_init(&info->alarm_lock); platform_set_drvdata(pdev, info); info->irq_alarm = platform_get_irq(pdev, 0); if (info->irq_alarm < 0) { dev_err(&pdev->dev, "no irq for alarm\n"); return info->irq_alarm; } dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n", info->irq_tick, info->irq_alarm); /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); info->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(info->base)) return PTR_ERR(info->base); info->rtc_clk = devm_clk_get(&pdev->dev, "rtc"); if (IS_ERR(info->rtc_clk)) { ret = PTR_ERR(info->rtc_clk); if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "failed to find rtc clock\n"); else dev_dbg(&pdev->dev, "probe deferred due to missing rtc clk\n"); return ret; } ret = clk_prepare_enable(info->rtc_clk); if (ret) return ret; if (info->data->needs_src_clk) { info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src"); if (IS_ERR(info->rtc_src_clk)) { ret = PTR_ERR(info->rtc_src_clk); if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "failed to find rtc source clock\n"); else dev_dbg(&pdev->dev, "probe deferred due to missing rtc src clk\n"); goto err_src_clk; } ret = clk_prepare_enable(info->rtc_src_clk); if (ret) goto err_src_clk; } /* check to see if everything is setup correctly */ if (info->data->enable) info->data->enable(info); dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", readw(info->base + S3C2410_RTCCON)); device_init_wakeup(&pdev->dev, 1); /* Check RTC Time */ if (s3c_rtc_gettime(&pdev->dev, &rtc_tm)) { rtc_tm.tm_year = 100; rtc_tm.tm_mon = 0; rtc_tm.tm_mday = 1; rtc_tm.tm_hour = 0; rtc_tm.tm_min = 0; rtc_tm.tm_sec = 0; s3c_rtc_settime(&pdev->dev, &rtc_tm); dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); } /* register RTC and exit */ info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, THIS_MODULE); if (IS_ERR(info->rtc)) { dev_err(&pdev->dev, "cannot attach rtc\n"); ret = PTR_ERR(info->rtc); goto err_nortc; } ret = devm_request_irq(&pdev->dev, info->irq_alarm, s3c_rtc_alarmirq, 0, "s3c2410-rtc alarm", info); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_alarm, ret); goto err_nortc; } ret = devm_request_irq(&pdev->dev, info->irq_tick, s3c_rtc_tickirq, 0, "s3c2410-rtc tick", info); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_tick, ret); goto err_nortc; } if (info->data->select_tick_clk) info->data->select_tick_clk(info); s3c_rtc_setfreq(info, 1); s3c_rtc_disable_clk(info); return 0; err_nortc: if (info->data->disable) info->data->disable(info); if (info->data->needs_src_clk) clk_disable_unprepare(info->rtc_src_clk); err_src_clk: clk_disable_unprepare(info->rtc_clk); return ret; }
static int s3c_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct rtc_time rtc_tm; struct resource *res; int ret; int tmp; dev_dbg(&pdev->dev, "%s: probe=%p\n", __func__, pdev); /* find the IRQs */ s3c_rtc_tickno = platform_get_irq(pdev, 1); if (s3c_rtc_tickno < 0) { dev_err(&pdev->dev, "no irq for rtc tick\n"); return s3c_rtc_tickno; } s3c_rtc_alarmno = platform_get_irq(pdev, 0); if (s3c_rtc_alarmno < 0) { dev_err(&pdev->dev, "no irq for alarm\n"); return s3c_rtc_alarmno; } dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n", s3c_rtc_tickno, s3c_rtc_alarmno); /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); s3c_rtc_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(s3c_rtc_base)) return PTR_ERR(s3c_rtc_base); rtc_clk = devm_clk_get(&pdev->dev, "rtc"); if (IS_ERR(rtc_clk)) { dev_err(&pdev->dev, "failed to find rtc clock source\n"); ret = PTR_ERR(rtc_clk); rtc_clk = NULL; return ret; } clk_prepare_enable(rtc_clk); /* check to see if everything is setup correctly */ s3c_rtc_enable(pdev, 1); dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", readw(s3c_rtc_base + S3C2410_RTCCON)); device_init_wakeup(&pdev->dev, 1); /* register RTC and exit */ rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, THIS_MODULE); if (IS_ERR(rtc)) { dev_err(&pdev->dev, "cannot attach rtc\n"); ret = PTR_ERR(rtc); goto err_nortc; } s3c_rtc_cpu_type = s3c_rtc_get_driver_data(pdev); /* Check RTC Time */ s3c_rtc_gettime(NULL, &rtc_tm); if (rtc_valid_tm(&rtc_tm)) { rtc_tm.tm_year = 100; rtc_tm.tm_mon = 0; rtc_tm.tm_mday = 1; rtc_tm.tm_hour = 0; rtc_tm.tm_min = 0; rtc_tm.tm_sec = 0; s3c_rtc_settime(NULL, &rtc_tm); dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); } if (s3c_rtc_cpu_type != TYPE_S3C2410) rtc->max_user_freq = 32768; else rtc->max_user_freq = 128; if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { tmp = readw(s3c_rtc_base + S3C2410_RTCCON); tmp |= S3C2443_RTCCON_TICSEL; writew(tmp, s3c_rtc_base + S3C2410_RTCCON); } platform_set_drvdata(pdev, rtc); s3c_rtc_setfreq(&pdev->dev, 1); ret = devm_request_irq(&pdev->dev, s3c_rtc_alarmno, s3c_rtc_alarmirq, 0, "s3c2410-rtc alarm", rtc); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); goto err_nortc; } ret = devm_request_irq(&pdev->dev, s3c_rtc_tickno, s3c_rtc_tickirq, 0, "s3c2410-rtc tick", rtc); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); goto err_nortc; } clk_disable(rtc_clk); return 0; err_nortc: s3c_rtc_enable(pdev, 0); clk_disable_unprepare(rtc_clk); return ret; }
static int __devinit s3c_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct rtc_time rtc_tm; struct resource *res; int ret; int tmp; pr_debug("%s: probe=%p\n", __func__, pdev); s3c_rtc_tickno = platform_get_irq(pdev, 1); if (s3c_rtc_tickno < 0) { dev_err(&pdev->dev, "no irq for rtc tick\n"); return -ENOENT; } s3c_rtc_alarmno = platform_get_irq(pdev, 0); if (s3c_rtc_alarmno < 0) { dev_err(&pdev->dev, "no irq for alarm\n"); return -ENOENT; } pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n", s3c_rtc_tickno, s3c_rtc_alarmno); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "failed to get memory region resource\n"); return -ENOENT; } s3c_rtc_mem = request_mem_region(res->start, resource_size(res), pdev->name); if (s3c_rtc_mem == NULL) { dev_err(&pdev->dev, "failed to reserve memory region\n"); ret = -ENOENT; goto err_nores; } s3c_rtc_base = ioremap(res->start, resource_size(res)); if (s3c_rtc_base == NULL) { dev_err(&pdev->dev, "failed ioremap()\n"); ret = -EINVAL; goto err_nomap; } rtc_clk = clk_get(&pdev->dev, "rtc"); if (IS_ERR(rtc_clk)) { dev_err(&pdev->dev, "failed to find rtc clock source\n"); ret = PTR_ERR(rtc_clk); rtc_clk = NULL; goto err_clk; } clk_enable(rtc_clk); s3c_rtc_enable(pdev, 1); pr_debug("s3c2410_rtc: RTCCON=%02x\n", readw(s3c_rtc_base + S3C2410_RTCCON)); device_init_wakeup(&pdev->dev, 1); rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops, THIS_MODULE); if (IS_ERR(rtc)) { dev_err(&pdev->dev, "cannot attach rtc\n"); ret = PTR_ERR(rtc); goto err_nortc; } s3c_rtc_cpu_type = s3c_rtc_get_driver_data(pdev); s3c_rtc_gettime(NULL, &rtc_tm); if (rtc_valid_tm(&rtc_tm)) { rtc_tm.tm_year = 100; rtc_tm.tm_mon = 0; rtc_tm.tm_mday = 1; rtc_tm.tm_hour = 0; rtc_tm.tm_min = 0; rtc_tm.tm_sec = 0; s3c_rtc_settime(NULL, &rtc_tm); dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); } if (s3c_rtc_cpu_type != TYPE_S3C2410) rtc->max_user_freq = 32768; else rtc->max_user_freq = 128; if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { tmp = readw(s3c_rtc_base + S3C2410_RTCCON); tmp |= S3C2443_RTCCON_TICSEL; writew(tmp, s3c_rtc_base + S3C2410_RTCCON); } platform_set_drvdata(pdev, rtc); s3c_rtc_setfreq(&pdev->dev, 1); ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq, 0, "s3c2410-rtc alarm", rtc); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); goto err_alarm_irq; } ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq, 0, "s3c2410-rtc tick", rtc); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); free_irq(s3c_rtc_alarmno, rtc); goto err_tick_irq; } clk_disable(rtc_clk); return 0; err_tick_irq: free_irq(s3c_rtc_alarmno, rtc); err_alarm_irq: platform_set_drvdata(pdev, NULL); rtc_device_unregister(rtc); err_nortc: s3c_rtc_enable(pdev, 0); clk_disable(rtc_clk); clk_put(rtc_clk); err_clk: iounmap(s3c_rtc_base); err_nomap: release_resource(s3c_rtc_mem); err_nores: return ret; }
static int __devinit s3c_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct rtc_time rtc_tm; struct resource *res; int ret; pr_debug("%s: probe=%p\n", __func__, pdev); /* find the IRQs */ s3c_rtc_tickno = platform_get_irq(pdev, 1); if (s3c_rtc_tickno < 0) { dev_err(&pdev->dev, "no irq for rtc tick\n"); return -ENOENT; } s3c_rtc_alarmno = platform_get_irq(pdev, 0); if (s3c_rtc_alarmno < 0) { dev_err(&pdev->dev, "no irq for alarm\n"); return -ENOENT; } pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n", s3c_rtc_tickno, s3c_rtc_alarmno); /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "failed to get memory region resource\n"); return -ENOENT; } s3c_rtc_mem = request_mem_region(res->start, res->end-res->start+1, pdev->name); if (s3c_rtc_mem == NULL) { dev_err(&pdev->dev, "failed to reserve memory region\n"); ret = -ENOENT; goto err_nores; } s3c_rtc_base = ioremap(res->start, res->end - res->start + 1); if (s3c_rtc_base == NULL) { dev_err(&pdev->dev, "failed ioremap()\n"); ret = -EINVAL; goto err_nomap; } rtc_clk = clk_get(&pdev->dev, "rtc"); if (IS_ERR(rtc_clk)) { dev_err(&pdev->dev, "failed to find rtc clock source\n"); ret = PTR_ERR(rtc_clk); rtc_clk = NULL; goto err_clk; } clk_enable(rtc_clk); /* check to see if everything is setup correctly */ s3c_rtc_enable(pdev, 1); pr_debug("s3c2410_rtc: RTCCON=%02x\n", readw(s3c_rtc_base + S3C2410_RTCCON)); device_init_wakeup(&pdev->dev, 1); /* register RTC and exit */ rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops, THIS_MODULE); if (IS_ERR(rtc)) { dev_err(&pdev->dev, "cannot attach rtc\n"); ret = PTR_ERR(rtc); goto err_nortc; } s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; /* Check RTC Time */ s3c_rtc_gettime(NULL, &rtc_tm); if (rtc_valid_tm(&rtc_tm)) { rtc_tm.tm_year = 100; rtc_tm.tm_mon = 0; rtc_tm.tm_mday = 1; rtc_tm.tm_hour = 0; rtc_tm.tm_min = 0; rtc_tm.tm_sec = 0; s3c_rtc_settime(NULL, &rtc_tm); dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); } if (s3c_rtc_cpu_type == TYPE_S3C64XX) rtc->max_user_freq = 32768; else rtc->max_user_freq = 128; platform_set_drvdata(pdev, rtc); s3c_rtc_setfreq(&pdev->dev, 1); return 0; err_nortc: s3c_rtc_enable(pdev, 0); clk_disable(rtc_clk); clk_put(rtc_clk); err_clk: iounmap(s3c_rtc_base); err_nomap: release_resource(s3c_rtc_mem); err_nores: return ret; }
static int __devinit s3c_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct resource *res; unsigned char bcd_tmp,bcd_loop; int ret; #ifdef CONFIG_RTC_DRV_MAX8998 struct rtc_time tm; #endif pr_debug("%s: probe=%p\n", __func__, pdev); /* find the IRQs */ s3c_rtc_tickno = platform_get_irq(pdev, 1); if (s3c_rtc_tickno < 0) { dev_err(&pdev->dev, "no irq for rtc tick\n"); return -ENOENT; } s3c_rtc_alarmno = platform_get_irq(pdev, 0); if (s3c_rtc_alarmno < 0) { dev_err(&pdev->dev, "no irq for alarm\n"); return -ENOENT; } pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n", s3c_rtc_tickno, s3c_rtc_alarmno); /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "failed to get memory region resource\n"); return -ENOENT; } s3c_rtc_mem = request_mem_region(res->start, res->end-res->start+1, pdev->name); if (s3c_rtc_mem == NULL) { dev_err(&pdev->dev, "failed to reserve memory region\n"); ret = -ENOENT; goto err_nores; } s3c_rtc_base = ioremap(res->start, res->end - res->start + 1); if (s3c_rtc_base == NULL) { dev_err(&pdev->dev, "failed ioremap()\n"); ret = -EINVAL; goto err_nomap; } /* check to see if everything is setup correctly */ s3c_rtc_enable(pdev, 1); pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(s3c_rtc_base + S3C2410_RTCCON)); s3c_rtc_setfreq(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1); #ifdef CONFIG_RTC_DRV_MAX8998 max8998_rtc_read_time(&tm); #endif /* register RTC and exit */ rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops, THIS_MODULE); if (IS_ERR(rtc)) { dev_err(&pdev->dev, "cannot attach rtc\n"); ret = PTR_ERR(rtc); goto err_nortc; } rtc->max_user_freq = S3C_MAX_CNT; #ifdef CONFIG_RTC_DRV_MAX8998 s3c_rtc_settime(rtc, &tm); //update from pmic #endif #ifdef SET_RTC_DEFAULT_RESET_TIME { struct rtc_time tm; s3c_rtc_gettime (pdev, &tm); if (rtc_valid_tm (&tm) != 0) { struct rtc_time reset_tm = { .tm_sec = DEFAULT_RESET_TIME_SEC, .tm_min = DEFAULT_RESET_TIME_MIN, .tm_hour = DEFAULT_RESET_TIME_HOUR, .tm_mday = DEFAULT_RESET_TIME_DATE, .tm_mon = DEFAULT_RESET_TIME_MON - 1, .tm_year = DEFAULT_RESET_TIME_YEAR - 1900, }; s3c_rtc_settime (pdev, &reset_tm); #ifdef CONFIG_RTC_DRV_MAX8998 max8998_rtc_set_time(&reset_tm); // also update pmic rtc as default #endif } } #else /* check rtc time */ for (bcd_loop = S3C2410_RTCSEC ; bcd_loop <= S3C2410_RTCYEAR ; bcd_loop +=0x4) { bcd_tmp = readb(s3c_rtc_base + bcd_loop); if(((bcd_tmp & 0xf) > 0x9) || ((bcd_tmp & 0xf0) > 0x90)) writeb(0, s3c_rtc_base + bcd_loop); } #endif /* SET_RTC_DEFAULT_RESET_TIME */ platform_set_drvdata(pdev, rtc); #ifdef CONFIG_RTC_S3C_SYNC_SYSTEM_TIME rtc_sync_start_save_delta(); #endif /* CONFIG_RTC_S3C_SYNC_SYSTEM_TIME */ return 0; err_nortc: s3c_rtc_enable(pdev, 0); iounmap(s3c_rtc_base); err_nomap: release_resource(s3c_rtc_mem); err_nores: return ret; } #ifdef CONFIG_PM /* RTC Power management control */ static struct timespec s3c_rtc_delta; static int ticnt_save; static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) { struct rtc_time tm; struct timespec time; time.tv_nsec = 0; /* save TICNT for anyone using periodic interrupts */ ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); s3c_rtc_gettime(&pdev->dev, &tm); rtc_tm_to_time(&tm, &time.tv_sec); save_time_delta(&s3c_rtc_delta, &time); if (gpio_get_value(GPIO_WLAN_BT_EN) == 0) /* BCM4329 isnt working */ s3c_rtc_enable(pdev, 0); #ifdef CONFIG_RTC_S3C_SYNC_SYSTEM_TIME cancel_delayed_work(&rtc_sync_work); #endif /* CONFIG_RTC_S3C_SYNC_SYSTEM_TIME */ return 0; } static int s3c_rtc_resume(struct platform_device *pdev) { struct rtc_time tm; struct timespec time; time.tv_nsec = 0; if (gpio_get_value(GPIO_WLAN_BT_EN) == 0) /* BCM4329 isnt working */ s3c_rtc_enable(pdev, 1); s3c_rtc_gettime(&pdev->dev, &tm); rtc_tm_to_time(&tm, &time.tv_sec); restore_time_delta(&s3c_rtc_delta, &time); writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); #ifdef CONFIG_RTC_S3C_SYNC_SYSTEM_TIME rtc_sync_start (); #endif return 0; } #else #define s3c_rtc_suspend NULL #define s3c_rtc_resume NULL #endif static struct platform_driver s3c2410_rtc_driver = { .probe = s3c_rtc_probe, .remove = __devexit_p(s3c_rtc_remove), .suspend = s3c_rtc_suspend, .resume = s3c_rtc_resume, .driver = { .name = "s3c2410-rtc", .owner = THIS_MODULE, }, }; static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics\n"; static int __init s3c_rtc_init(void) { printk(banner); return platform_driver_register(&s3c2410_rtc_driver); }
static int s3c_rtc_driver_probe(struct vmm_device *pdev, const struct vmm_devtree_nodeid *devid) { u32 alarmno, tickno; struct rtc_time rtc_tm; int ret, tmp, rc; /* find the IRQs */ rc = vmm_devtree_irq_get(pdev->node, &alarmno, 0); if (rc) { rc = VMM_EFAIL; return rc; } s3c_rtc_alarmno = alarmno; rc = vmm_devtree_irq_get(pdev->node, &tickno, 1); if (rc) { rc = VMM_EFAIL; return rc; } s3c_rtc_tickno = tickno; /* get the memory region */ rc = vmm_devtree_regmap(pdev->node, (virtual_addr_t *)&s3c_rtc_base, 0); if (rc) { dev_err(pdev, "failed ioremap()\n"); ret = rc; goto err_nomap; } rtc_clk = clk_get(pdev, "rtc"); if (rtc_clk == NULL) { dev_err(pdev, "failed to find rtc clock source\n"); ret = -ENODEV; goto err_clk; } clk_enable(rtc_clk); /* check to see if everything is setup correctly */ s3c_rtc_enable(pdev, 1); //device_init_wakeup(pdev, 1); /* register RTC and exit */ s3c_rtcops.dev = pdev; rc = vmm_rtcdev_register(&s3c_rtcops); if (rc) { dev_err(pdev, "cannot attach rtc\n"); ret = rc; goto err_nortc; } s3c_rtc_cpu_type = (enum s3c_cpu_type)devid->data; /* Check RTC Time */ s3c_rtc_gettime(NULL, &rtc_tm); if (!rtc_valid_tm(&rtc_tm)) { dev_warn(pdev, "warning: invalid RTC value so initializing it\n"); rtc_tm.tm_year = 100; rtc_tm.tm_mon = 0; rtc_tm.tm_mday = 1; rtc_tm.tm_hour = 0; rtc_tm.tm_min = 0; rtc_tm.tm_sec = 0; s3c_rtc_settime(NULL, &rtc_tm); } if (s3c_rtc_cpu_type != TYPE_S3C2410) max_user_freq = 32768; else max_user_freq = 128; if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { tmp = readw(s3c_rtc_base + S3C2410_RTCCON); tmp |= S3C2443_RTCCON_TICSEL; writew(tmp, s3c_rtc_base + S3C2410_RTCCON); } pdev->priv = &s3c_rtcops; s3c_rtc_setfreq(&s3c_rtcops, 1); if ((rc = vmm_host_irq_register(s3c_rtc_alarmno, "s3c_rtc_alarm", s3c_rtc_alarmirq, &s3c_rtcops))) { dev_err(pdev, "IRQ%d error %d\n", s3c_rtc_alarmno, rc); goto err_alarm_irq; } if ((rc = vmm_host_irq_register(s3c_rtc_tickno, "s3c_rtc_tick", s3c_rtc_tickirq, &s3c_rtcops))) { dev_err(pdev, "IRQ%d error %d\n", s3c_rtc_tickno, rc); goto err_tick_irq; } clk_disable(rtc_clk); return 0; err_tick_irq: vmm_host_irq_unregister(s3c_rtc_alarmno, &s3c_rtcops); err_alarm_irq: pdev->priv = NULL; vmm_rtcdev_unregister(&s3c_rtcops); err_nortc: s3c_rtc_enable(pdev, 0); clk_disable(rtc_clk); clk_put(rtc_clk); err_clk: vmm_devtree_regunmap(pdev->node, (virtual_addr_t) s3c_rtc_base, 0); err_nomap: return ret; }
static int s3c_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct resource *res; int ret; //unsigned char bcd_tmp,bcd_loop; pr_debug("%s: probe=%p\n", __func__, pdev); /* find the IRQs */ s3c_rtc_tickno = platform_get_irq(pdev, 1); if (s3c_rtc_tickno < 0) { dev_err(&pdev->dev, "no irq for rtc tick\n"); return -ENOENT; } s3c_rtc_alarmno = platform_get_irq(pdev, 0); if (s3c_rtc_alarmno < 0) { dev_err(&pdev->dev, "no irq for alarm\n"); return -ENOENT; } printk("s3c_rtc: tick irq %d, alarm irq %d\n", s3c_rtc_tickno, s3c_rtc_alarmno); /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "failed to get memory region resource\n"); return -ENOENT; } s3c_rtc_mem = request_mem_region(res->start, res->end-res->start+1, pdev->name); if (s3c_rtc_mem == NULL) { dev_err(&pdev->dev, "failed to reserve memory region\n"); ret = -ENOENT; goto err_nores; } s3c_rtc_base = ioremap(res->start, res->end - res->start + 1); if (s3c_rtc_base == NULL) { dev_err(&pdev->dev, "failed ioremap()\n"); ret = -EINVAL; goto err_nomap; } /* check to see if everything is setup correctly */ s3c_rtc_enable(pdev, 1); pr_debug("s3c_rtc: RTCCON=%02x\n", readb(s3c_rtc_base + S3C_RTCCON)); s3c_rtc_setfreq(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1); /* register RTC and exit */ rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops, THIS_MODULE); if (IS_ERR(rtc)) { dev_err(&pdev->dev, "cannot attach rtc\n"); ret = PTR_ERR(rtc); goto err_nortc; } rtc->max_user_freq = S3C_MAX_CNT; #ifdef SET_RTC_DEFAULT_RESET_TIME { struct rtc_time tm; s3c_rtc_gettime (pdev, &tm); if (rtc_valid_tm (&tm) != 0) { struct rtc_time reset_tm = { .tm_sec = DEFAULT_RESET_TIME_SEC, .tm_min = DEFAULT_RESET_TIME_MIN, .tm_hour = DEFAULT_RESET_TIME_HOUR, .tm_mday = DEFAULT_RESET_TIME_DATE, .tm_mon = DEFAULT_RESET_TIME_MON - 1, .tm_year = DEFAULT_RESET_TIME_YEAR - 1900, }; s3c_rtc_settime (pdev, &reset_tm); } } #else /* check rtc time */ for (bcd_loop = S3C_RTCSEC ; bcd_loop <= S3C_RTCYEAR ; bcd_loop +=0x4) { bcd_tmp = readb(s3c_rtc_base + bcd_loop); if(((bcd_tmp & 0xf) > 0x9) || ((bcd_tmp & 0xf0) > 0x90)) writeb(0, s3c_rtc_base + bcd_loop); } #endif platform_set_drvdata(pdev, rtc); #ifdef CONFIG_RTC_SYNC rtc_sync_start_save_delta(); #endif /* CONFIG_RTC_SYNC */ return 0; err_nortc: s3c_rtc_enable(pdev, 0); iounmap(s3c_rtc_base); err_nomap: release_resource(s3c_rtc_mem); err_nores: return ret; } #ifdef CONFIG_PM /* RTC Power management control */ static int ticnt_save; static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) { /* save TICNT for anyone using periodic interrupts */ ticnt_save = readb(s3c_rtc_base + S3C_TICNT); s3c_rtc_enable(pdev, 0); #ifdef CONFIG_RTC_SYNC cancel_delayed_work(&rtc_sync_work); #endif /* CONFIG_RTC_SYNC */ return 0; }