Exemplo n.º 1
0
static int __devinit tps80031_rtc_probe(struct platform_device *pdev)
{
	struct tps80031_platform_data *tps80031_pdata;
	struct tps80031_rtc_platform_data *pdata;
	struct tps80031_rtc *rtc;
	struct rtc_time tm;
	int err;
	u8 reg;

	tps80031_pdata = dev_get_platdata(pdev->dev.parent);
	if (!tps80031_pdata) {
		dev_err(&pdev->dev, "no tps80031 platform_data specified\n");
		return -EINVAL;
	}

	pdata = tps80031_pdata->rtc_pdata;
	if (!pdata) {
		dev_err(&pdev->dev, "no platform_data specified\n");
		return -EINVAL;
	}

	rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
	if (!rtc)
		return -ENOMEM;

	rtc->irq = -1;
	if (pdata->irq < 0)
		dev_err(&pdev->dev, "no IRQ specified, wakeup is disabled\n");

	rtc->msecure_gpio = -1;
	if (gpio_is_valid(pdata->msecure_gpio)) {
		err = gpio_request(pdata->msecure_gpio, "tps80031 msecure");
		if (err == 0) {
			rtc->msecure_gpio = pdata->msecure_gpio;
			gpio_direction_output(rtc->msecure_gpio, 0);
		} else
			dev_warn(&pdev->dev, "could not get msecure GPIO\n");
	}

	rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
				       &tps80031_rtc_ops, THIS_MODULE);
	dev_set_drvdata(&pdev->dev, rtc);

	if (IS_ERR(rtc->rtc)) {
		err = PTR_ERR(rtc->rtc);
		goto fail;
	}

	if ((int)pdev && (int)&pdev->dev)
		err = tps80031_read_regs(&pdev->dev, RTC_STATUS, 1, &reg);
	else {
		dev_err(&pdev->dev, "%s Input params incorrect\n", __func__);
		err = -EBUSY;
		goto fail;
	}

	if (err) {
		dev_err(&pdev->dev, "%s unable to read status\n", __func__);
		err = -EBUSY;
		goto fail;
	}

	/* If RTC have POR values, set time using platform data*/
	tps80031_rtc_read_time(&pdev->dev, &tm);
	if ((tm.tm_year == RTC_YEAR_OFFSET + RTC_POR_YEAR) &&
		(tm.tm_mon == (RTC_POR_MONTH - 1)) &&
		(tm.tm_mday == RTC_POR_DAY)) {
		if (pdata->time.tm_year < 2000 ||
			pdata->time.tm_year > 2100) {
			dev_err(&pdev->dev, "Invalid platform data\n");
			memset(&pdata->time, 0, sizeof(pdata->time));
			pdata->time.tm_year = 2011;
			pdata->time.tm_mday = 1;
		}
		tps80031_rtc_set_time(&pdev->dev, &pdata->time);
	}

	reg = ALARM_INT_STATUS;
	err = tps80031_write_regs(&pdev->dev, RTC_STATUS, 1, &reg);
	if (err) {
		dev_err(&pdev->dev, "unable to program RTC_STATUS reg\n");
		return -EBUSY;
	}

	tps80031_enable_rtc_write(&pdev->dev);
	err = tps80031_set_bits(pdev->dev.parent, 1, RTC_INT, ENABLE_ALARM_INT);
	tps80031_disable_rtc_write(&pdev->dev);
	if (err) {
		dev_err(&pdev->dev, "unable to program Interrupt Mask reg\n");
		err = -EBUSY;
		rtc->alarm_irq_enabled = 0;
		goto fail;
	} else
		rtc->alarm_irq_enabled = 1;

	if (pdata && (pdata->irq >= 0)) {
		rtc->irq = pdata->irq;
		err = request_threaded_irq(pdata->irq, NULL, tps80031_rtc_irq,
					IRQF_ONESHOT, "rtc_tps80031",
					&pdev->dev);
		if (err) {
			dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq);
			rtc->irq = -1;
		} else {
			device_init_wakeup(&pdev->dev, 1);
			enable_irq_wake(rtc->irq);
		}
	}
	return 0;

fail:
	if (!IS_ERR_OR_NULL(rtc->rtc))
		rtc_device_unregister(rtc->rtc);
	kfree(rtc);
	return err;
}
Exemplo n.º 2
0
static int tps80031_rtc_probe(struct platform_device *pdev)
{
	struct tps80031_rtc *rtc;
	struct rtc_time tm;
	int ret;

	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
	if (!rtc)
		return -ENOMEM;

	rtc->irq = platform_get_irq(pdev, 0);
	platform_set_drvdata(pdev, rtc);

	/* Start RTC */
	ret = tps80031_set_bits(pdev->dev.parent, TPS80031_SLAVE_ID1,
			TPS80031_RTC_CTRL_REG, STOP_RTC);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to start RTC. err = %d\n", ret);
		return ret;
	}

	/* If RTC have POR values, set time 01:01:2000 */
	tps80031_rtc_read_time(&pdev->dev, &tm);
	if ((tm.tm_year == RTC_YEAR_OFFSET + TPS80031_RTC_POR_YEAR) &&
		(tm.tm_mon == (TPS80031_RTC_POR_MONTH - 1)) &&
		(tm.tm_mday == TPS80031_RTC_POR_DAY)) {
		tm.tm_year = 2000;
		tm.tm_mday = 1;
		tm.tm_mon = 1;
		ret = tps80031_rtc_set_time(&pdev->dev, &tm);
		if (ret < 0) {
			dev_err(&pdev->dev,
				"RTC set time failed, err = %d\n", ret);
			return ret;
		}
	}

	/* Clear alarm intretupt status if it is there */
	ret = clear_alarm_int_status(&pdev->dev, rtc);
	if (ret < 0) {
		dev_err(&pdev->dev, "Clear alarm int failed, err = %d\n", ret);
		return ret;
	}

	rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
			       &tps80031_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc->rtc)) {
		ret = PTR_ERR(rtc->rtc);
		dev_err(&pdev->dev, "RTC registration failed, err %d\n", ret);
		return ret;
	}

	ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
			tps80031_rtc_irq,
			IRQF_ONESHOT | IRQF_EARLY_RESUME,
			dev_name(&pdev->dev), rtc);
	if (ret < 0) {
		dev_err(&pdev->dev, "request IRQ:%d failed, err = %d\n",
			 rtc->irq, ret);
		rtc_device_unregister(rtc->rtc);
		return ret;
	}
	device_set_wakeup_capable(&pdev->dev, 1);
	return 0;
}