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; }