static int twl_rtc_probe(struct platform_device *pdev)
{
	struct rtc_device *rtc;
	int ret = -EINVAL;
	int irq = platform_get_irq(pdev, 0);
	u8 rd_reg;

	if (irq <= 0)
		goto out1;

	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
	if (ret < 0)
		goto out1;

	if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
		dev_warn(&pdev->dev, "Power up reset detected.\n");

	if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
		dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");

	/* Clear RTC Power up reset and pending alarm interrupts */
	ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
	if (ret < 0)
		goto out1;

	if (twl_class_is_6030()) {
		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
			REG_INT_MSK_LINE_A);
		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
			REG_INT_MSK_STS_A);
	}

	dev_info(&pdev->dev, "Enabling TWL-RTC\n");
	ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG);
	if (ret < 0)
		goto out1;

	/* ensure interrupts are disabled, bootloaders can be strange */
	ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG);
	if (ret < 0)
		dev_warn(&pdev->dev, "unable to disable interrupt\n");

	/* init cached IRQ enable bits */
	ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
	if (ret < 0)
		goto out1;

	rtc = rtc_device_register(pdev->name,
				  &pdev->dev, &twl_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc)) {
		ret = PTR_ERR(rtc);
		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
			PTR_ERR(rtc));
		goto out1;
	}

	ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
				   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
				   dev_name(&rtc->dev), rtc);
	if (ret < 0) {
		dev_err(&pdev->dev, "IRQ is not free.\n");
		goto out2;
	}

	platform_set_drvdata(pdev, rtc);
	device_init_wakeup(&pdev->dev, 1);
	return 0;

out2:
	rtc_device_unregister(rtc);
out1:
	return ret;
}
static int AMI8563_probe(struct i2c_adapter *adapter, int address, int kind)
{
	struct AMI8563 *pAMI8563 = NULL;
	struct i2c_client *client = NULL;
	struct rtc_device *rtc = NULL;
	u8 value = 0;
	int err = 0;
	
	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
		err = -ENODEV;
		goto exit;
	}

	if(address != AMI8563_ADDR) {
		err = -EIO;
		goto exit;
	}

	if (!(pAMI8563 = kzalloc(sizeof(struct AMI8563), GFP_KERNEL))) {
		err = -ENOMEM;
		goto exit;
	}
	
	pAMI8563->alarm_status_power_on = 0;	
	client = &pAMI8563->client;
	client->addr = address;
	client->driver = &AMI8563_driver;
	client->adapter = adapter;
	strlcpy(client->name, AMI8563_driver.driver.name, I2C_NAME_SIZE);

	/* detect chip and check the alarm status*/
	err = i2c_ami8563_read(client, AMI8563_REG_ST2);
	if (err<0) {		
		goto exit_kfree;
	} else if (err&0x08) {
		ami8563_info("Power up as alarm on\n");
		pAMI8563->alarm_status_power_on = 1;
	}

	value = i2c_ami8563_read(client, AMI8563_REG_YR);
	ami8563_info("current year %d\n", value);
	value = bcd2bin(value);
#define CURRENT_YEAR (9) // 2009
	if (value>30 || value<CURRENT_YEAR) {
		ami8563_err("Detect invalid year %d, reset to default\n", value+2000);
		i2c_ami8563_write(client, AMI8563_REG_YR, bin2bcd(CURRENT_YEAR));
	}

	if ((err = i2c_attach_client(client)))
		goto exit_kfree;

	rtc = rtc_device_register(AMI8563_driver.driver.name, &client->dev,
				&AMI8563_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc)) {
		err = PTR_ERR(rtc);
		goto exit_detach;
	}

	i2c_set_clientdata(client, rtc);
	g_client = client;

	/*Clear AF,enable AIE*/
	//micco_enable_rtc_alarm_irq(0);
	value = i2c_ami8563_read(client, AMI8563_REG_ST2);
	value &= ~0x1<<3;
	value |= 0x1<<1;
	i2c_ami8563_write(client, AMI8563_REG_ST2, value);
	micco_enable_rtc_alarm_irq(1);
		
	//err = pmic_callback_register(PMIC_EVENT_EXTON, AMI8563_alarm_event_handler);
	
	AMI8563_sync_pxa3xx_rtc(client);

	register_reboot_notifier(&ami_sys_reboot_nb); /* for enter into recovery mode */
#ifdef CONFIG_YUHUA_MISC_DEV	
	set_rtc_detect(1);
#endif
	
	printk("Rtc ami8563 drv register succ\n");
	return 0;

exit_detach:
	i2c_detach_client(client);
exit_kfree:
	kfree(pAMI8563);
exit:
	ami8563_err("err %d\n", err);
	return err;
}
示例#3
0
static int tps65910_rtc_probe(struct platform_device *pdev)
{
	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
	struct tps65910_rtc *tps65910_rtc;
	int per_irq;
	int alm_irq;
	int ret = 0;
	u8 rtc_ctl;
	
	struct rtc_time tm;
	struct rtc_time tm_def = {	//	2012.1.1 12:00:00 Saturday
			.tm_wday = 6,
			.tm_year = 111,
			.tm_mon = 0,
			.tm_mday = 1,
			.tm_hour = 12,
			.tm_min = 0,
			.tm_sec = 0,
		};
	
	tps65910_rtc = kzalloc(sizeof(*tps65910_rtc), GFP_KERNEL);
	if (tps65910_rtc == NULL)
		return -ENOMEM;

	platform_set_drvdata(pdev, tps65910_rtc);
	tps65910_rtc->tps65910 = tps65910;
	per_irq = tps65910->irq_base + TPS65910_IRQ_RTC_PERIOD;
	alm_irq = tps65910->irq_base + TPS65910_IRQ_RTC_ALARM;
	
	/* Take rtc out of reset */
	ret = tps65910_reg_read(tps65910, TPS65910_DEVCTRL);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to read TPS65910_DEVCTRL: %d\n", ret);
		return ret;
	}

	if(ret & BIT_RTC_PWDN)
	{
		rtc_ctl = ret & (~BIT_RTC_PWDN);

		ret = tps65910_reg_write(tps65910, TPS65910_DEVCTRL, rtc_ctl);
		if (ret < 0) {
			dev_err(&pdev->dev, "Failed to write RTC control: %d\n", ret);
			return ret;
		}
	}
	
	/*start rtc default*/
	ret = tps65910_reg_read(tps65910, TPS65910_RTC_CTRL);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to read RTC control: %d\n", ret);
		return ret;
	}

	if(!(ret & BIT_RTC_CTRL_REG_STOP_RTC_M))
	{
		rtc_ctl = ret | BIT_RTC_CTRL_REG_STOP_RTC_M;

		ret = tps65910_reg_write(tps65910, TPS65910_RTC_CTRL, rtc_ctl);
		if (ret < 0) {
			dev_err(&pdev->dev, "Failed to write RTC control: %d\n", ret);
			return ret;
		}
	}
	
	ret = tps65910_reg_read(tps65910, TPS65910_RTC_STATUS);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to read RTC status: %d\n", ret);
		return ret;
	}
		
	/*set init time*/
	ret = tps65910_rtc_readtime(&pdev->dev, &tm);
	if (ret)
	{
		dev_err(&pdev->dev, "Failed to read RTC time\n");
		return ret;
	}
	
	ret = rtc_valid_tm(&tm);
	if (ret) {
		dev_err(&pdev->dev,"invalid date/time and init time\n");
		tps65910_rtc_set_time(&pdev->dev, &tm_def); // 2011-01-01 12:00:00
		dev_info(&pdev->dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
				1900 + tm_def.tm_year, tm_def.tm_mon + 1, tm_def.tm_mday, tm_def.tm_wday,
				tm_def.tm_hour, tm_def.tm_min, tm_def.tm_sec);
	}

	device_init_wakeup(&pdev->dev, 1);

	tps65910_rtc->rtc = rtc_device_register("tps65910", &pdev->dev,
					      &tps65910_rtc_ops, THIS_MODULE);
	if (IS_ERR(tps65910_rtc->rtc)) {
		ret = PTR_ERR(tps65910_rtc->rtc);
		goto err;
	}

	/*request rtc and alarm irq of tps65910*/
	ret = request_threaded_irq(per_irq, NULL, tps65910_per_irq,
				   IRQF_TRIGGER_RISING, "RTC period",
				   tps65910_rtc);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n",
			per_irq, ret);
	}

	ret = request_threaded_irq(alm_irq, NULL, tps65910_alm_irq,
				   IRQF_TRIGGER_RISING, "RTC alarm",
				   tps65910_rtc);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
			alm_irq, ret);
	}

	//for rtc irq test
	//tps65910_set_bits(tps65910_rtc->tps65910, TPS65910_RTC_INTERRUPTS,
	//			       BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);

	enable_irq_wake(alm_irq); // so tps65910 alarm irq can wake up system
	g_pdev = pdev;
	
	printk("%s:ok\n",__func__);
	
	return 0;

err:
	kfree(tps65910_rtc);
	return ret;
}

static int __devexit tps65910_rtc_remove(struct platform_device *pdev)
{
	struct tps65910_rtc *tps65910_rtc = platform_get_drvdata(pdev);
	int per_irq = tps65910_rtc->tps65910->irq_base + TPS65910_IRQ_RTC_PERIOD;
	int alm_irq = tps65910_rtc->tps65910->irq_base + TPS65910_IRQ_RTC_ALARM;

	free_irq(alm_irq, tps65910_rtc);
	free_irq(per_irq, tps65910_rtc);
	rtc_device_unregister(tps65910_rtc->rtc);
	kfree(tps65910_rtc);

	return 0;
}

static const struct dev_pm_ops tps65910_rtc_pm_ops = {
	.suspend = tps65910_rtc_suspend,
	.resume = tps65910_rtc_resume,

	.freeze = tps65910_rtc_freeze,
	.thaw = tps65910_rtc_resume,
	.restore = tps65910_rtc_resume,

	.poweroff = tps65910_rtc_suspend,
};

static struct platform_driver tps65910_rtc_driver = {
	.probe = tps65910_rtc_probe,
	.remove = __devexit_p(tps65910_rtc_remove),
	.driver = {
		.name = "tps65910-rtc",
		.pm = &tps65910_rtc_pm_ops,
	},
};

static ssize_t rtc_tps65910_test_write(struct file *file, 
			const char __user *buf, size_t count, loff_t *offset)
{
	char nr_buf[8];
	int nr = 0, ret;
	struct platform_device *pdev;	
	struct rtc_time tm;
	struct rtc_wkalrm alrm;
	struct tps65910_rtc *tps65910_rtc;
	
	if(count > 3)
		return -EFAULT;
	ret = copy_from_user(nr_buf, buf, count);
	if(ret < 0)
		return -EFAULT;

	sscanf(nr_buf, "%d", &nr);
	if(nr > 5 || nr < 0)
	{
		printk("%s:data is error\n",__func__);
		return -EFAULT;
	}

	if(!g_pdev)
		return -EFAULT;
	else
		pdev = g_pdev;

	
	tps65910_rtc = dev_get_drvdata(&pdev->dev);
	
	//test rtc time
	if(nr == 0)
	{	
		tm.tm_wday = 6;
		tm.tm_year = 111;
		tm.tm_mon = 0;
		tm.tm_mday = 1;
		tm.tm_hour = 12;
		tm.tm_min = 0;
		tm.tm_sec = 0;
	
		ret = tps65910_rtc_set_time(&pdev->dev, &tm); // 2011-01-01 12:00:00
		if (ret)
		{
			dev_err(&pdev->dev, "Failed to set RTC time\n");
			return -EFAULT;
		}

	}
	
	/*set init time*/
	ret = tps65910_rtc_readtime(&pdev->dev, &tm);
	if (ret)
		dev_err(&pdev->dev, "Failed to read RTC time\n");
	else
		dev_info(&pdev->dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
			1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_wday,
			tm.tm_hour, tm.tm_min, tm.tm_sec);
		
	if(!ret)
	printk("%s:ok\n",__func__);
	else
	printk("%s:error\n",__func__);
	

	//test rtc alarm
	if(nr == 2)
	{
		//2000-01-01 00:00:30
		if(tm.tm_sec < 30)
		{
			alrm.time.tm_sec = tm.tm_sec+30;	
			alrm.time.tm_min = tm.tm_min;
		}
		else
		{
			alrm.time.tm_sec = tm.tm_sec-30;
			alrm.time.tm_min = tm.tm_min+1;
		}
		alrm.time.tm_hour = tm.tm_hour;
		alrm.time.tm_mday = tm.tm_mday;
		alrm.time.tm_mon = tm.tm_mon;
		alrm.time.tm_year = tm.tm_year;		
		tps65910_rtc_alarm_irq_enable(&pdev->dev, 1);
		tps65910_rtc_setalarm(&pdev->dev, &alrm);

		dev_info(&pdev->dev, "Set alarm %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
				1900 + alrm.time.tm_year, alrm.time.tm_mon + 1, alrm.time.tm_mday, alrm.time.tm_wday,
				alrm.time.tm_hour, alrm.time.tm_min, alrm.time.tm_sec);
	}

	
	if(nr == 3)
	{	
		ret = tps65910_reg_read(tps65910_rtc->tps65910, TPS65910_RTC_STATUS);
		if (ret < 0) {
			printk("%s:Failed to read RTC status: %d\n", __func__, ret);
			return ret;
		}
		printk("%s:ret=0x%x\n",__func__,ret&0xff);

		ret = tps65910_reg_write(tps65910_rtc->tps65910, TPS65910_RTC_STATUS, ret&0xff);
		if (ret < 0) {
			printk("%s:Failed to read RTC status: %d\n", __func__, ret);
			return ret;
		}
	}

	if(nr == 4)
	tps65910_rtc_update_irq_enable(&pdev->dev, 1);

	if(nr == 5)
	tps65910_rtc_update_irq_enable(&pdev->dev, 0);
	
	return count;
}
示例#4
0
static int __devinit s2mps11_rtc_probe(struct platform_device *pdev)
{
	struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
	struct sec_pmic_platform_data *pdata = dev_get_platdata(iodev->dev);
	struct s2mps11_rtc_info *s2mps11;
	int ret;

	s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_rtc_info),
				GFP_KERNEL);
	if (!s2mps11)
		return -ENOMEM;

	s2mps11->dev = &pdev->dev;
	s2mps11->iodev = iodev;

	s2mps11->wtsr_smpl = pdata->wtsr_smpl;
	s2mps11->jig_smpl_disable = pdata->jig_smpl_disable;

	s2mps11->irq = pdata->irq_base + S2MPS11_IRQ_RTCA0;

	platform_set_drvdata(pdev, s2mps11);

	ret = s2mps11_rtc_init_reg(s2mps11);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret);
		goto out_rtc;
	}

	pmic_is_jig_attached = s2mps11_rtc_is_jigonb_low(s2mps11);

	if (s2mps11->jig_smpl_disable && pmic_is_jig_attached)
		s2mps11->wtsr_smpl = false;
	if (s2mps11->wtsr_smpl) {
		s2mps11_rtc_enable_wtsr(s2mps11, true);
		s2mps11_rtc_enable_smpl(s2mps11, true);
	} else {
		s2mps11_rtc_enable_wtsr(s2mps11, false);
		s2mps11_rtc_enable_smpl(s2mps11, false);
	}

	device_init_wakeup(&pdev->dev, true);

	s2mps11->rtc_dev = rtc_device_register("s2mps11-rtc", &pdev->dev,
			&s2mps11_rtc_ops, THIS_MODULE);

	if (IS_ERR(s2mps11->rtc_dev)) {
		ret = PTR_ERR(s2mps11->rtc_dev);
		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
		goto out_rtc;
	}

	ret = request_threaded_irq(s2mps11->irq, NULL, s2mps11_rtc_alarm_irq, 0,
			"rtc-alarm0", s2mps11);

	if (ret < 0)
		dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
			s2mps11->irq, ret);

	return 0;

out_rtc:
	devm_kfree(&pdev->dev, s2mps11);
	platform_set_drvdata(pdev, NULL);
	return ret;
}
static int __devinit rs5c348_probe(struct spi_device *spi)
{
	int ret;
	struct rtc_device *rtc;
	struct rs5c348_plat_data *pdata;

	pdata = kzalloc(sizeof(struct rs5c348_plat_data), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;
	spi->dev.platform_data = pdata;

	/* Check D7 of SECOND register */
	ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_SECS));
	if (ret < 0 || (ret & 0x80)) {
		dev_err(&spi->dev, "not found.\n");
		goto kfree_exit;
	}

	dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n");
	dev_info(&spi->dev, "spiclk %u KHz.\n",
		 (spi->max_speed_hz + 500) / 1000);

	/* turn RTC on if it was not on */
	ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
	if (ret < 0)
		goto kfree_exit;
	if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) {
		u8 buf[2];
		struct rtc_time tm;
		if (ret & RS5C348_BIT_VDET)
			dev_warn(&spi->dev, "voltage-low detected.\n");
		if (ret & RS5C348_BIT_XSTP)
			dev_warn(&spi->dev, "oscillator-stop detected.\n");
		rtc_time_to_tm(0, &tm);	/* 1970/1/1 */
		ret = rs5c348_rtc_set_time(&spi->dev, &tm);
		if (ret < 0)
			goto kfree_exit;
		buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
		buf[1] = 0;
		ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
		if (ret < 0)
			goto kfree_exit;
	}

	ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL1));
	if (ret < 0)
		goto kfree_exit;
	if (ret & RS5C348_BIT_24H)
		pdata->rtc_24h = 1;

	rtc = rtc_device_register(rs5c348_driver.driver.name, &spi->dev,
				  &rs5c348_rtc_ops, THIS_MODULE);

	if (IS_ERR(rtc)) {
		ret = PTR_ERR(rtc);
		goto kfree_exit;
	}

	pdata->rtc = rtc;

	return 0;
 kfree_exit:
	kfree(pdata);
	return ret;
}
示例#6
0
static int __devinit rx8025_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct rx8025_data *rx8025;
	int err, need_reset = 0;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
				     | I2C_FUNC_SMBUS_I2C_BLOCK)) {
		dev_err(&adapter->dev,
			"doesn't support required functionality\n");
		err = -EIO;
		goto errout;
	}

	rx8025 = kzalloc(sizeof(*rx8025), GFP_KERNEL);
	if (!rx8025) {
		dev_err(&adapter->dev, "failed to alloc memory\n");
		err = -ENOMEM;
		goto errout;
	}

	rx8025->client = client;
	i2c_set_clientdata(client, rx8025);
	INIT_WORK(&rx8025->work, rx8025_work);

	err = rx8025_init_client(client, &need_reset);
	if (err)
		goto errout_free;

	if (need_reset) {
		struct rtc_time tm;
		dev_info(&client->dev,
			 "bad conditions detected, resetting date\n");
		rtc_time_to_tm(0, &tm);	
		rx8025_set_time(&client->dev, &tm);
	}

	rx8025->rtc = rtc_device_register(client->name, &client->dev,
					  &rx8025_rtc_ops, THIS_MODULE);
	if (IS_ERR(rx8025->rtc)) {
		err = PTR_ERR(rx8025->rtc);
		dev_err(&client->dev, "unable to register the class device\n");
		goto errout_free;
	}

	if (client->irq > 0) {
		dev_info(&client->dev, "IRQ %d supplied\n", client->irq);
		err = request_irq(client->irq, rx8025_irq,
				  0, "rx8025", client);
		if (err) {
			dev_err(&client->dev, "unable to request IRQ\n");
			goto errout_reg;
		}
	}

	rx8025->rtc->irq_freq = 1;
	rx8025->rtc->max_user_freq = 1;

	err = rx8025_sysfs_register(&client->dev);
	if (err)
		goto errout_irq;

	return 0;

errout_irq:
	if (client->irq > 0)
		free_irq(client->irq, client);

errout_reg:
	rtc_device_unregister(rx8025->rtc);

errout_free:
	i2c_set_clientdata(client, NULL);
	kfree(rx8025);

errout:
	dev_err(&adapter->dev, "probing for rx8025 failed\n");
	return err;
}
示例#7
0
static int __devinit
vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
{
	int retval = 0;
	unsigned char rtc_control;

	/* There can be only one ... */
	if (mrst_rtc.dev)
		return -EBUSY;

	if (!iomem)
		return -ENODEV;

	iomem = request_mem_region(iomem->start, resource_size(iomem),
				   driver_name);
	if (!iomem) {
		dev_dbg(dev, "i/o mem already in use.\n");
		return -EBUSY;
	}

	mrst_rtc.irq = rtc_irq;
	mrst_rtc.iomem = iomem;
	mrst_rtc.dev = dev;
	dev_set_drvdata(dev, &mrst_rtc);

	mrst_rtc.rtc = rtc_device_register(driver_name, dev,
				&mrst_rtc_ops, THIS_MODULE);
	if (IS_ERR(mrst_rtc.rtc)) {
		retval = PTR_ERR(mrst_rtc.rtc);
		goto cleanup0;
	}

	rename_region(iomem, dev_name(&mrst_rtc.rtc->dev));

	spin_lock_irq(&rtc_lock);
	mrst_irq_disable(&mrst_rtc, RTC_PIE | RTC_AIE);
	rtc_control = vrtc_cmos_read(RTC_CONTROL);
	spin_unlock_irq(&rtc_lock);

	if (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))
		dev_dbg(dev, "TODO: support more than 24-hr BCD mode\n");

	if (rtc_irq) {
		retval = request_irq(rtc_irq, mrst_rtc_irq,
				IRQF_DISABLED, dev_name(&mrst_rtc.rtc->dev),
				mrst_rtc.rtc);
		if (retval < 0) {
			dev_dbg(dev, "IRQ %d is already in use, err %d\n",
				rtc_irq, retval);
			goto cleanup1;
		}
	}
	dev_dbg(dev, "initialised\n");
	return 0;

cleanup1:
	rtc_device_unregister(mrst_rtc.rtc);
cleanup0:
	dev_set_drvdata(dev, NULL);
	mrst_rtc.dev = NULL;
	release_mem_region(iomem->start, resource_size(iomem));
	dev_err(dev, "rtc-mrst: unable to initialise\n");
	return retval;
}
示例#8
0
static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
{
	struct rtc_device *rtc;
	int ret = 0;
	int irq = platform_get_irq(pdev, 0);
	u8 rd_reg;

	if (irq < 0)
		return irq;

	rtc = rtc_device_register(pdev->name,
				  &pdev->dev, &twl4030_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc)) {
		ret = -EINVAL;
		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
			PTR_ERR(rtc));
		goto out0;

	}

	platform_set_drvdata(pdev, rtc);

	ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);

	if (ret < 0)
		goto out1;

	if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
		dev_warn(&pdev->dev, "Power up reset detected.\n");

	if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
		dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");

	/* Clear RTC Power up reset and pending alarm interrupts */
	ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
	if (ret < 0)
		goto out1;

	ret = request_irq(irq, twl4030_rtc_interrupt,
				IRQF_TRIGGER_RISING,
				rtc->dev.bus_id, rtc);
	if (ret < 0) {
		dev_err(&pdev->dev, "IRQ is not free.\n");
		goto out1;
	}

	/* Check RTC module status, Enable if it is off */
	ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
	if (ret < 0)
		goto out2;

	if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
		dev_info(&pdev->dev, "Enabling TWL4030-RTC.\n");
		rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
		ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
		if (ret < 0)
			goto out2;
	}

	/* init cached IRQ enable bits */
	ret = twl4030_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
	if (ret < 0)
		goto out2;

	return ret;


out2:
	free_irq(irq, rtc);
out1:
	rtc_device_unregister(rtc);
out0:
	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;
}
示例#11
0
static int __init stk17ta8_rtc_probe(struct platform_device *pdev)
{
    struct rtc_device *rtc;
    struct resource *res;
    unsigned int cal;
    unsigned int flags;
    struct rtc_plat_data *pdata;
    void __iomem *ioaddr = NULL;
    int ret = 0;

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!res)
        return -ENODEV;

    pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
    if (!pdata)
        return -ENOMEM;
    pdata->irq = -1;
    if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) {
        ret = -EBUSY;
        goto out;
    }
    pdata->baseaddr = res->start;
    ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE);
    if (!ioaddr) {
        ret = -ENOMEM;
        goto out;
    }
    pdata->ioaddr = ioaddr;
    pdata->irq = platform_get_irq(pdev, 0);

    /* turn RTC on if it was not on */
    cal = readb(ioaddr + RTC_CALIBRATION);
    if (cal & RTC_STOP) {
        cal &= RTC_CAL_MASK;
        flags = readb(ioaddr + RTC_FLAGS);
        writeb(flags | RTC_WRITE, ioaddr + RTC_FLAGS);
        writeb(cal, ioaddr + RTC_CALIBRATION);
        writeb(flags & ~RTC_WRITE, ioaddr + RTC_FLAGS);
    }
    if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_PF)
        dev_warn(&pdev->dev, "voltage-low detected.\n");

    if (pdata->irq >= 0) {
        writeb(0, ioaddr + RTC_INTERRUPTS);
        if (request_irq(pdata->irq, stk17ta8_rtc_interrupt,
                        IRQF_DISABLED | IRQF_SHARED,
                        pdev->name, pdev) < 0) {
            dev_warn(&pdev->dev, "interrupt not available.\n");
            pdata->irq = -1;
        }
    }

    rtc = rtc_device_register(pdev->name, &pdev->dev,
                              &stk17ta8_rtc_ops, THIS_MODULE);
    if (IS_ERR(rtc)) {
        ret = PTR_ERR(rtc);
        goto out;
    }
    pdata->rtc = rtc;
    pdata->last_jiffies = jiffies;
    platform_set_drvdata(pdev, pdata);
    ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
    if (ret)
        goto out;
    return 0;
out:
    if (pdata->rtc)
        rtc_device_unregister(pdata->rtc);
    if (pdata->irq >= 0)
        free_irq(pdata->irq, pdev);
    if (ioaddr)
        iounmap(ioaddr);
    if (pdata->baseaddr)
        release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
    kfree(pdata);
    return ret;
}
示例#12
0
static int ds1511_rtc_probe(struct platform_device *pdev)
{
	struct rtc_device *rtc;
	struct resource *res;
	struct rtc_plat_data *pdata;
	int ret = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		return -ENODEV;
	}
	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;
	pdata->size = resource_size(res);
	if (!devm_request_mem_region(&pdev->dev, res->start, pdata->size,
			pdev->name))
		return -EBUSY;
	ds1511_base = devm_ioremap(&pdev->dev, res->start, pdata->size);
	if (!ds1511_base)
		return -ENOMEM;
	pdata->ioaddr = ds1511_base;
	pdata->irq = platform_get_irq(pdev, 0);

	/*
	 * turn on the clock and the crystal, etc.
	 */
	rtc_write(0, RTC_CMD);
	rtc_write(0, RTC_CMD1);
	/*
	 * clear the wdog counter
	 */
	rtc_write(0, DS1511_WD_MSEC);
	rtc_write(0, DS1511_WD_SEC);
	/*
	 * start the clock
	 */
	rtc_enable_update();

	/*
	 * check for a dying bat-tree
	 */
	if (rtc_read(RTC_CMD1) & DS1511_BLF1) {
		dev_warn(&pdev->dev, "voltage-low detected.\n");
	}

	spin_lock_init(&pdata->lock);
	platform_set_drvdata(pdev, pdata);
	/*
	 * if the platform has an interrupt in mind for this device,
	 * then by all means, set it
	 */
	if (pdata->irq > 0) {
		rtc_read(RTC_CMD1);
		if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt,
			IRQF_SHARED, pdev->name, pdev) < 0) {

			dev_warn(&pdev->dev, "interrupt not available.\n");
			pdata->irq = 0;
		}
	}

	rtc = rtc_device_register(pdev->name, &pdev->dev, &ds1511_rtc_ops,
		THIS_MODULE);
	if (IS_ERR(rtc))
		return PTR_ERR(rtc);
	pdata->rtc = rtc;

	ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);
	if (ret)
		rtc_device_unregister(pdata->rtc);
	return ret;
}
static int __devinit jz4740_rtc_probe(struct platform_device *pdev)
{
	int ret;
	struct jz4740_rtc *rtc;
	uint32_t scratchpad;

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

	rtc->irq = platform_get_irq(pdev, 0);
	if (rtc->irq < 0) {
		ret = -ENOENT;
		dev_err(&pdev->dev, "Failed to get platform irq\n");
		goto err_free;
	}

	rtc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!rtc->mem) {
		ret = -ENOENT;
		dev_err(&pdev->dev, "Failed to get platform mmio memory\n");
		goto err_free;
	}

	rtc->mem = request_mem_region(rtc->mem->start, resource_size(rtc->mem),
					pdev->name);
	if (!rtc->mem) {
		ret = -EBUSY;
		dev_err(&pdev->dev, "Failed to request mmio memory region\n");
		goto err_free;
	}

	rtc->base = ioremap_nocache(rtc->mem->start, resource_size(rtc->mem));
	if (!rtc->base) {
		ret = -EBUSY;
		dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
		goto err_release_mem_region;
	}

	spin_lock_init(&rtc->lock);

	platform_set_drvdata(pdev, rtc);

	device_init_wakeup(&pdev->dev, 1);

	rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops,
					THIS_MODULE);
	if (IS_ERR(rtc->rtc)) {
		ret = PTR_ERR(rtc->rtc);
		dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret);
		goto err_iounmap;
	}

	ret = request_irq(rtc->irq, jz4740_rtc_irq, 0,
				pdev->name, rtc);
	if (ret) {
		dev_err(&pdev->dev, "Failed to request rtc irq: %d\n", ret);
		goto err_unregister_rtc;
	}

	scratchpad = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD);
	if (scratchpad != 0x12345678) {
		ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678);
		ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0);
		if (ret) {
			dev_err(&pdev->dev, "Could not write write to RTC registers\n");
			goto err_free_irq;
		}
	}

	return 0;

err_free_irq:
	free_irq(rtc->irq, rtc);
err_unregister_rtc:
	rtc_device_unregister(rtc->rtc);
err_iounmap:
	platform_set_drvdata(pdev, NULL);
	iounmap(rtc->base);
err_release_mem_region:
	release_mem_region(rtc->mem->start, resource_size(rtc->mem));
err_free:
	kfree(rtc);

	return ret;
}
示例#14
0
static int __devinit twl_rtc_probe(struct platform_device *pdev)
{
	struct rtc_device *rtc;
	int ret = 0;
	int irq = platform_get_irq(pdev, 0);
	u8 rd_reg;

	if (irq <= 0)
		return -EINVAL;

	rtc = rtc_device_register(pdev->name,
				  &pdev->dev, &twl_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc)) {
		ret = PTR_ERR(rtc);
		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
			PTR_ERR(rtc));
		goto out0;

	}

	platform_set_drvdata(pdev, rtc);

	/* Starting backup batery charge - configuration 3v, 25uA */
	ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, 0x12 /*BB_CFG*/);

	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
	if (ret < 0)
		goto out1;

	if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
		dev_warn(&pdev->dev, "Power up reset detected.\n");

	if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
		dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");

	/* Clear RTC Power up reset and pending alarm interrupts */
	ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
	if (ret < 0)
		goto out1;

	ret = request_irq(irq, twl_rtc_interrupt,
				IRQF_TRIGGER_RISING,
				dev_name(&rtc->dev), rtc);
	if (ret < 0) {
		dev_err(&pdev->dev, "IRQ is not free.\n");
		goto out1;
	}

	if (twl_class_is_6030()) {
		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
			REG_INT_MSK_LINE_A);
		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
			REG_INT_MSK_STS_A);
	}

	/* Check RTC module status, Enable if it is off */
	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
	if (ret < 0)
		goto out2;

	if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
		dev_info(&pdev->dev, "Enabling TWL-RTC.\n");
		rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
		ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
		if (ret < 0)
			goto out2;
	}

	/* init cached IRQ enable bits */
	ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
	if (ret < 0)
		goto out2;

#ifdef WORKQUEUE_RTC
	omap_rtc_wq = create_workqueue(MY_WORK_QUEUE_NAME);
#endif

	return ret;

out2:
	free_irq(irq, rtc);
out1:
	rtc_device_unregister(rtc);
out0:
	return ret;
}
static int __init mc13xxx_rtc_probe(struct platform_device *pdev)
{
	int ret;
	struct mc13xxx_rtc *priv;
	struct mc13xxx *mc13xxx;
	int rtcrst_pending;

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

	mc13xxx = dev_get_drvdata(pdev->dev.parent);
	priv->mc13xxx = mc13xxx;

	platform_set_drvdata(pdev, priv);

	mc13xxx_lock(mc13xxx);

	ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST,
			mc13xxx_rtc_reset_handler, DRIVER_NAME, priv);
	if (ret)
		goto err_reset_irq_request;

	ret = mc13xxx_irq_status(mc13xxx, MC13XXX_IRQ_RTCRST,
			NULL, &rtcrst_pending);
	if (ret)
		goto err_reset_irq_status;

	priv->valid = !rtcrst_pending;

	ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_1HZ,
			mc13xxx_rtc_update_handler, DRIVER_NAME, priv);
	if (ret)
		goto err_update_irq_request;

	ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA,
			mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv);
	if (ret)
		goto err_alarm_irq_request;

	mc13xxx_unlock(mc13xxx);

	priv->rtc = rtc_device_register(pdev->name,
			&pdev->dev, &mc13xxx_rtc_ops, THIS_MODULE);
	if (IS_ERR(priv->rtc)) {
		ret = PTR_ERR(priv->rtc);

		mc13xxx_lock(mc13xxx);

		mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv);
err_alarm_irq_request:

		mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv);
err_update_irq_request:

err_reset_irq_status:

		mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv);
err_reset_irq_request:

		mc13xxx_unlock(mc13xxx);

		platform_set_drvdata(pdev, NULL);
		kfree(priv);
	}

	return ret;
}
示例#16
0
static int tps6591x_rtc_probe(struct platform_device *pdev)
{
	struct tps6591x_rtc_platform_data *pdata = pdev->dev.platform_data;
	struct tps6591x_rtc *rtc;
	struct rtc_time tm;
	int err;
	u8 reg;

	rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);

	if (!rtc)
		return -ENOMEM;

	rtc->irq = -1;

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

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

	dev_set_drvdata(&pdev->dev, rtc);
	device_init_wakeup(&pdev->dev, 1);
	rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
				       &tps6591x_rtc_ops, THIS_MODULE);

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

	if ((int)pdev && (int)&pdev->dev)
		err = tps6591x_read_regs(&pdev->dev, RTC_STATUS, 1, &reg);
	else {
		dev_err(&pdev->dev, "\n %s Input params incorrect\n", __func__);
		return -EBUSY;
	}
	if (err) {
		dev_err(&pdev->dev, "\n %s unable to read status\n", __func__);
		return -EBUSY;
	}

	reg = RTC_BBCH_SEL | RTC_BBCH_EN;
	tps6591x_write_regs(&pdev->dev, RTC_BBCH_REG, 1, &reg);
	if (err) {
		dev_err(&pdev->dev, "unable to program Charger reg\n");
		return -EBUSY;
	}

	err = tps6591x_rtc_start(&pdev->dev);
	if (err) {
		dev_err(&pdev->dev, "unable to start RTC\n");
		return -EBUSY;
	}

	tps6591x_rtc_read_time(&pdev->dev, &tm);

	if (tps6591x_rtc_valid_tm(&tm) < 0) {
		if (pdata->time.tm_year < 2000 || pdata->time.tm_year >= 2100) {
			memset(&pdata->time, 0, sizeof(pdata->time));
			pdata->time.tm_year = 2000;
			pdata->time.tm_mday = 1;
		}
		pdata->time.tm_year -= OS_REF_YEAR;
		tps6591x_rtc_set_time(&pdev->dev, &pdata->time);
	}

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

	reg = ENABLE_ALARM_INT;
	tps6591x_write_regs(&pdev->dev, RTC_INT, 1, &reg);
	if (err) {
		dev_err(&pdev->dev, "unable to program Interrupt Mask reg\n");
		return -EBUSY;
	}

	if (pdata && (pdata->irq >= 0)) {
		rtc->irq = pdata->irq;
		err = request_threaded_irq(pdata->irq, NULL, tps6591x_rtc_irq,
					IRQF_ONESHOT, "rtc_tps6591x",
					&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;
}
示例#17
0
static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
{
	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
	struct m48t59_private *m48t59 = NULL;
	struct resource *res;
	int ret = -ENOMEM;
	char *name;
	const struct rtc_class_ops *ops;

	/* This chip could be memory-mapped or I/O-mapped */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
		if (!res)
			return -EINVAL;
	}

	if (res->flags & IORESOURCE_IO) {
		/* If we are I/O-mapped, the platform should provide
		 * the operations accessing chip registers.
		 */
		if (!pdata || !pdata->write_byte || !pdata->read_byte)
			return -EINVAL;
	} else if (res->flags & IORESOURCE_MEM) {
		/* we are memory-mapped */
		if (!pdata) {
			pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
			if (!pdata)
				return -ENOMEM;
			/* Ensure we only kmalloc platform data once */
			pdev->dev.platform_data = pdata;
		}
		if (!pdata->type)
			pdata->type = M48T59RTC_TYPE_M48T59;

		/* Try to use the generic memory read/write ops */
		if (!pdata->write_byte)
			pdata->write_byte = m48t59_mem_writeb;
		if (!pdata->read_byte)
			pdata->read_byte = m48t59_mem_readb;
	}

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

	m48t59->ioaddr = pdata->ioaddr;

	if (!m48t59->ioaddr) {
		/* ioaddr not mapped externally */
		m48t59->ioaddr = ioremap(res->start, res->end - res->start + 1);
		if (!m48t59->ioaddr)
			goto out;
	}

	/* Try to get irq number. We also can work in
	 * the mode without IRQ.
	 */
	m48t59->irq = platform_get_irq(pdev, 0);
	if (m48t59->irq <= 0)
		m48t59->irq = NO_IRQ;

	if (m48t59->irq != NO_IRQ) {
		ret = request_irq(m48t59->irq, m48t59_rtc_interrupt,
			IRQF_SHARED, "rtc-m48t59", &pdev->dev);
		if (ret)
			goto out;
	}
	switch (pdata->type) {
	case M48T59RTC_TYPE_M48T59:
		name = "m48t59";
		ops = &m48t59_rtc_ops;
		pdata->offset = 0x1ff0;
		break;
	case M48T59RTC_TYPE_M48T02:
		name = "m48t02";
		ops = &m48t02_rtc_ops;
		pdata->offset = 0x7f0;
		break;
	case M48T59RTC_TYPE_M48T08:
		name = "m48t08";
		ops = &m48t02_rtc_ops;
		pdata->offset = 0x1ff0;
		break;
	default:
		dev_err(&pdev->dev, "Unknown RTC type\n");
		ret = -ENODEV;
		goto out;
	}

	m48t59->rtc = rtc_device_register(name, &pdev->dev, ops, THIS_MODULE);
	if (IS_ERR(m48t59->rtc)) {
		ret = PTR_ERR(m48t59->rtc);
		goto out;
	}

	m48t59_nvram_attr.size = pdata->offset;

	ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
	if (ret)
		goto out;

	spin_lock_init(&m48t59->lock);
	platform_set_drvdata(pdev, m48t59);
	return 0;

out:
	if (!IS_ERR(m48t59->rtc))
		rtc_device_unregister(m48t59->rtc);
	if (m48t59->irq != NO_IRQ)
		free_irq(m48t59->irq, &pdev->dev);
	if (m48t59->ioaddr)
		iounmap(m48t59->ioaddr);
	if (m48t59)
		kfree(m48t59);
	return ret;
}
示例#18
0
/*
 * probe for dryice rtc device
 */
static int dryice_rtc_probe(struct platform_device *pdev)
{
	struct rtc_device *rtc;
	struct resource *res;
	struct rtc_drv_data *pdata = NULL;
	void __iomem *ioaddr = NULL;
	int rc = 0;

	dev_dbg(&pdev->dev, "%s\n", __func__);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

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

	pdata->pdev = pdev;
	pdata->irq = -1;
	pdata->size = res->end - res->start + 1;

	if (!request_mem_region(res->start, pdata->size, pdev->name)) {
		rc = -EBUSY;
		goto err;
	}
	pdata->baseaddr = res->start;
	ioaddr = ioremap(pdata->baseaddr, pdata->size);
	if (!ioaddr) {
		rc = -ENOMEM;
		goto err;
	}
	pdata->ioaddr = ioaddr;
	pdata->irq = platform_get_irq(pdev, 0);

	init_waitqueue_head(&pdata->write_wait);

	INIT_WORK(&pdata->work, dryice_work);

	mutex_init(&pdata->write_mutex);

	pdata->clk = clk_get(NULL, "dryice_clk");
	clk_enable(pdata->clk);

	if (pdata->irq >= 0) {
		if (request_irq(pdata->irq, dryice_norm_irq, IRQF_SHARED,
				pdev->name, pdata) < 0) {
			dev_warn(&pdev->dev, "interrupt not available.\n");
			pdata->irq = -1;
			goto err;
		}
	}

	/*
	 * Initialize dryice hardware
	 */

	/* put dryice into valid state */
	if (di_read(pdata, DSR) & DSR_NVF)
		di_write_wait_err(pdata, DSR_NVF | DSR_SVF, DSR, rc, err);

	/* mask alarm interrupt */
	di_int_disable(pdata, DIER_CAIE);

	/* initialize alarm */
	di_write_wait_err(pdata, DCAMR_UNSET, DCAMR, rc, err);
	di_write_wait_err(pdata, 0, DCALR, rc, err);

	/* clear alarm flag */
	if (di_read(pdata, DSR) & DSR_CAF)
		di_write_wait_err(pdata, DSR_CAF, DSR, rc, err);

	/* the timer won't count if it has never been written to */
	if (!di_read(pdata, DTCMR))
		di_write_wait_err(pdata, 0, DTCMR, rc, err);

	/* start keeping time */
	if (!(di_read(pdata, DCR) & DCR_TCE))
		di_write_wait_err(pdata, di_read(pdata, DCR) | DCR_TCE, DCR,
				  rc, err);

	rtc = rtc_device_register(pdev->name, &pdev->dev,
				  &dryice_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc)) {
		rc = PTR_ERR(rtc);
		goto err;
	}
	pdata->rtc = rtc;
	platform_set_drvdata(pdev, pdata);

	return 0;
err:
	if (pdata->rtc)
		rtc_device_unregister(pdata->rtc);

	if (pdata->irq >= 0)
		free_irq(pdata->irq, pdata);

	if (pdata->clk) {
		clk_disable(pdata->clk);
		clk_put(pdata->clk);
	}

	if (pdata->ioaddr)
		iounmap(pdata->ioaddr);

	if (pdata->baseaddr)
		release_mem_region(pdata->baseaddr, pdata->size);

	kfree(pdata);

	return rc;
}
示例#19
0
static int s35390a_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	int err;
	unsigned int i;
	struct s35390a *s35390a;
	struct rtc_time tm;
	char buf[1];

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		err = -ENODEV;
		goto exit;
	}

	s35390a = kzalloc(sizeof(struct s35390a), GFP_KERNEL);
	if (!s35390a) {
		err = -ENOMEM;
		goto exit;
	}

	s35390a->client[0] = client;
	i2c_set_clientdata(client, s35390a);

	/* This chip uses multiple addresses, use dummy devices for them */
	for (i = 1; i < 8; ++i) {
		s35390a->client[i] = i2c_new_dummy(client->adapter,
					client->addr + i);
		if (!s35390a->client[i]) {
			dev_err(&client->dev, "Address %02x unavailable\n",
						client->addr + i);
			err = -EBUSY;
			goto exit_dummy;
		}
	}

	err = s35390a_reset(s35390a);
	if (err < 0) {
		dev_err(&client->dev, "error resetting chip\n");
		goto exit_dummy;
	}

	err = s35390a_disable_test_mode(s35390a);
	if (err < 0) {
		dev_err(&client->dev, "error disabling test mode\n");
		goto exit_dummy;
	}

	err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf));
	if (err < 0) {
		dev_err(&client->dev, "error checking 12/24 hour mode\n");
		goto exit_dummy;
	}
	if (buf[0] & S35390A_FLAG_24H)
		s35390a->twentyfourhour = 1;
	else
		s35390a->twentyfourhour = 0;

	if (s35390a_get_datetime(client, &tm) < 0)
		dev_warn(&client->dev, "clock needs to be set\n");

	INIT_WORK(&s35390a->work, s35390a_work);

	if (client->irq > 0) {
		err = request_irq(client->irq, s35390a_irq, IRQF_TRIGGER_LOW,
				client->name, client);
		if (err) {
			dev_err(&client->dev, "unable to request IRQ\n");
			goto exit_dummy;
		}
	}

	s35390a->rtc = rtc_device_register(s35390a_driver.driver.name,
				&client->dev, &s35390a_rtc_ops, THIS_MODULE);

	if (IS_ERR(s35390a->rtc)) {
		err = PTR_ERR(s35390a->rtc);
		goto exit_intr;
	}
	s35390a->rtc->irq_freq = 0;
	s35390a->rtc->max_user_freq = 16;
	return 0;

exit_intr:
	free_irq(client->irq, client);

exit_dummy:
	for (i = 1; i < 8; ++i)
		if (s35390a->client[i])
			i2c_unregister_device(s35390a->client[i]);
	kfree(s35390a);
	i2c_set_clientdata(client, NULL);

exit:
	return err;
}
示例#20
0
static int rtc_probe(struct platform_device *pdev)
{
	struct v3020_platform_data *pdata = pdev->dev.platform_data;
	struct v3020 *chip;
	int retval = -EBUSY;
	int i;
	int temp;

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

	if (pdata->use_gpio)
		chip->ops = &v3020_gpio_ops;
	else
		chip->ops = &v3020_mmio_ops;

	retval = chip->ops->map_io(chip, pdev, pdata);
	if (retval)
		goto err_chip;

	/* Make sure the v3020 expects a communication cycle
	 * by reading 8 times */
	for (i = 0; i < 8; i++)
		temp = chip->ops->read_bit(chip);

	/* Test chip by doing a write/read sequence
	 * to the chip ram */
	v3020_set_reg(chip, V3020_SECONDS, 0x33);
	if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
		retval = -ENODEV;
		goto err_io;
	}

	/* Make sure frequency measurement mode, test modes, and lock
	 * are all disabled */
	v3020_set_reg(chip, V3020_STATUS_0, 0x0);

	if (pdata->use_gpio)
		dev_info(&pdev->dev, "Chip available at GPIOs "
			 "%d, %d, %d, %d\n",
			 chip->gpio[V3020_CS].gpio, chip->gpio[V3020_WR].gpio,
			 chip->gpio[V3020_RD].gpio, chip->gpio[V3020_IO].gpio);
	else
		dev_info(&pdev->dev, "Chip available at "
			 "physical address 0x%llx,"
			 "data connected to D%d\n",
			 (unsigned long long)pdev->resource[0].start,
			 chip->leftshift);

	platform_set_drvdata(pdev, chip);

	chip->rtc = rtc_device_register("v3020",
				&pdev->dev, &v3020_rtc_ops, THIS_MODULE);
	if (IS_ERR(chip->rtc)) {
		retval = PTR_ERR(chip->rtc);
		goto err_io;
	}

	return 0;

err_io:
	chip->ops->unmap_io(chip);
err_chip:
	kfree(chip);

	return retval;
}
示例#21
0
static int INITSECTION
cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
{
	struct cmos_rtc_board_info	*info = dev->platform_data;
	int				retval = 0;
	unsigned char			rtc_control;
	unsigned			address_space;

	/* there can be only one ... */
	if (cmos_rtc.dev)
		return -EBUSY;

	if (!ports)
		return -ENODEV;

	/* Claim I/O ports ASAP, minimizing conflict with legacy driver.
	 *
	 * REVISIT non-x86 systems may instead use memory space resources
	 * (needing ioremap etc), not i/o space resources like this ...
	 */
	ports = request_region(ports->start,
			ports->end + 1 - ports->start,
			driver_name);
	if (!ports) {
		dev_dbg(dev, "i/o registers already in use\n");
		return -EBUSY;
	}

	cmos_rtc.irq = rtc_irq;
	cmos_rtc.iomem = ports;

	/* Heuristic to deduce NVRAM size ... do what the legacy NVRAM
	 * driver did, but don't reject unknown configs.   Old hardware
	 * won't address 128 bytes.  Newer chips have multiple banks,
	 * though they may not be listed in one I/O resource.
	 */
#if	defined(CONFIG_ATARI)
	address_space = 64;
#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__sparc__)
	address_space = 128;
#else
#warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes.
	address_space = 128;
#endif
	if (can_bank2 && ports->end > (ports->start + 1))
		address_space = 256;

	/* For ACPI systems extension info comes from the FADT.  On others,
	 * board specific setup provides it as appropriate.  Systems where
	 * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and
	 * some almost-clones) can provide hooks to make that behave.
	 *
	 * Note that ACPI doesn't preclude putting these registers into
	 * "extended" areas of the chip, including some that we won't yet
	 * expect CMOS_READ and friends to handle.
	 */
	if (info) {
		if (info->rtc_day_alarm && info->rtc_day_alarm < 128)
			cmos_rtc.day_alrm = info->rtc_day_alarm;
		if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128)
			cmos_rtc.mon_alrm = info->rtc_mon_alarm;
		if (info->rtc_century && info->rtc_century < 128)
			cmos_rtc.century = info->rtc_century;

		if (info->wake_on && info->wake_off) {
			cmos_rtc.wake_on = info->wake_on;
			cmos_rtc.wake_off = info->wake_off;
		}
	}

	cmos_rtc.rtc = rtc_device_register(driver_name, dev,
				&cmos_rtc_ops, THIS_MODULE);
	if (IS_ERR(cmos_rtc.rtc)) {
		retval = PTR_ERR(cmos_rtc.rtc);
		goto cleanup0;
	}

	cmos_rtc.dev = dev;
	dev_set_drvdata(dev, &cmos_rtc);
	rename_region(ports, cmos_rtc.rtc->class_dev.class_id);

	spin_lock_irq(&rtc_lock);

	/* force periodic irq to CMOS reset default of 1024Hz;
	 *
	 * REVISIT it's been reported that at least one x86_64 ALI mobo
	 * doesn't use 32KHz here ... for portability we might need to
	 * do something about other clock frequencies.
	 */
	cmos_rtc.rtc->irq_freq = 1024;
	hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq);
	CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT);

	/* disable irqs */
	cmos_irq_disable(&cmos_rtc, RTC_PIE | RTC_AIE | RTC_UIE);

	rtc_control = CMOS_READ(RTC_CONTROL);

	spin_unlock_irq(&rtc_lock);

	/* FIXME teach the alarm code how to handle binary mode;
	 * <asm-generic/rtc.h> doesn't know 12-hour mode either.
	 */
	if (is_valid_irq(rtc_irq) &&
	    (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) {
		dev_dbg(dev, "only 24-hr BCD mode supported\n");
		retval = -ENXIO;
		goto cleanup1;
	}

	if (is_valid_irq(rtc_irq)) {
		irq_handler_t rtc_cmos_int_handler;

		if (is_hpet_enabled())
			rtc_cmos_int_handler = hpet_rtc_interrupt;
		else
			rtc_cmos_int_handler = rtc_interrupt;

		retval = request_irq(rtc_irq, rtc_cmos_int_handler,
				IRQF_DISABLED, cmos_rtc.rtc->class_dev.class_id,
				&cmos_rtc.rtc->class_dev);
		if (retval < 0) {
			dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
			goto cleanup1;
		}
	}
	hpet_rtc_timer_init();

	/* export at least the first block of NVRAM */
	nvram.size = address_space - NVRAM_OFFSET;
	retval = sysfs_create_bin_file(&dev->kobj, &nvram);
	if (retval < 0) {
		dev_dbg(dev, "can't create nvram file? %d\n", retval);
		goto cleanup2;
	}

	pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n",
			cmos_rtc.rtc->class_dev.class_id,
			is_valid_irq(rtc_irq)
				?  (cmos_rtc.mon_alrm
					? "year"
					: (cmos_rtc.day_alrm
						? "month" : "day"))
				: "no",
			cmos_rtc.century ? ", y3k" : "",
			nvram.size,
			is_hpet_enabled() ? ", hpet irqs" : "");

	return 0;

cleanup2:
	if (is_valid_irq(rtc_irq))
		free_irq(rtc_irq, &cmos_rtc.rtc->class_dev);
cleanup1:
	cmos_rtc.dev = NULL;
	rtc_device_unregister(cmos_rtc.rtc);
cleanup0:
	release_region(ports->start, ports->end + 1 - ports->start);
	return retval;
}
static int __devinit pm8xxx_rtc_probe(struct platform_device *pdev)
{
	int rc;
	u8 ctrl_reg;
	bool rtc_write_enable = false;
	struct pm8xxx_rtc *rtc_dd;
	struct resource *rtc_resource;
	const struct pm8xxx_rtc_platform_data *pdata =
						dev_get_platdata(&pdev->dev);

	if (pdata != NULL)
		rtc_write_enable = pdata->rtc_write_enable;

	rtc_dd = kzalloc(sizeof(*rtc_dd), GFP_KERNEL);
	if (rtc_dd == NULL) {
		dev_err(&pdev->dev, "Unable to allocate memory!\n");
		return -ENOMEM;
	}

	/* Initialise spinlock to protect RTC control register */
	spin_lock_init(&rtc_dd->ctrl_reg_lock);

	rtc_dd->rtc_alarm_irq = platform_get_irq(pdev, 0);
	if (rtc_dd->rtc_alarm_irq < 0) {
		dev_err(&pdev->dev, "Alarm IRQ resource absent!\n");
		rc = -ENXIO;
		goto fail_rtc_enable;
	}

	rtc_resource = platform_get_resource_byname(pdev, IORESOURCE_IO,
							"pmic_rtc_base");
	if (!(rtc_resource && rtc_resource->start)) {
		dev_err(&pdev->dev, "RTC IO resource absent!\n");
		rc = -ENXIO;
		goto fail_rtc_enable;
	}

	rtc_dd->rtc_base = rtc_resource->start;

	/* Setup RTC register addresses */
	rtc_dd->rtc_write_base = rtc_dd->rtc_base + PM8XXX_RTC_WRITE_OFFSET;
	rtc_dd->rtc_read_base = rtc_dd->rtc_base + PM8XXX_RTC_READ_OFFSET;
	rtc_dd->alarm_rw_base = rtc_dd->rtc_base + PM8XXX_ALARM_RW_OFFSET;

	rtc_dd->rtc_dev = &pdev->dev;

	/* Check if the RTC is on, else turn it on */
	rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
	if (rc < 0) {
		dev_err(&pdev->dev, "RTC control register read failed!\n");
		goto fail_rtc_enable;
	}

	if (!(ctrl_reg & PM8xxx_RTC_ENABLE)) {
		ctrl_reg |= PM8xxx_RTC_ENABLE;
		rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base,
									1);
		if (rc < 0) {
			dev_err(&pdev->dev, "Write to RTC control register "
								"failed\n");
			goto fail_rtc_enable;
		}
	}

	/* Enable abort enable feature */
	ctrl_reg |= PM8xxx_RTC_ABORT_ENABLE;
	rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
	if (rc < 0) {
		dev_err(&pdev->dev, "PM8xxx write failed!\n");
		goto fail_rtc_enable;
	}

	rtc_dd->ctrl_reg = ctrl_reg;
	if (rtc_write_enable == true)
		pm8xxx_rtc_ops.set_time = pm8xxx_rtc_set_time;

	platform_set_drvdata(pdev, rtc_dd);

	device_init_wakeup(&pdev->dev, 1);

	/* Register the RTC device */
	rtc_dd->rtc = rtc_device_register("pm8xxx_rtc", &pdev->dev,
				&pm8xxx_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc_dd->rtc)) {
		dev_err(&pdev->dev, "%s: RTC registration failed (%ld)\n",
					__func__, PTR_ERR(rtc_dd->rtc));
		rc = PTR_ERR(rtc_dd->rtc);
		goto fail_rtc_enable;
	}

	/* Request the alarm IRQ */
	rc = request_any_context_irq(rtc_dd->rtc_alarm_irq,
				 pm8xxx_alarm_trigger, IRQF_TRIGGER_RISING,
				 "pm8xxx_rtc_alarm", rtc_dd);
	if (rc < 0) {
		dev_err(&pdev->dev, "Request IRQ failed (%d)\n", rc);
		goto fail_req_irq;
	}

	dev_dbg(&pdev->dev, "Probe success !!\n");

	return 0;

fail_req_irq:
	rtc_device_unregister(rtc_dd->rtc);
fail_rtc_enable:
	platform_set_drvdata(pdev, NULL);
	kfree(rtc_dd);
	return rc;
}
static int __devinit spear_rtc_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct spear_rtc_config *config;
	unsigned int status = 0;
	int irq;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "no resource defined\n");
		return -EBUSY;
	}
	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
		dev_err(&pdev->dev, "rtc region already claimed\n");
		return -EBUSY;
	}

	config = kzalloc(sizeof(*config), GFP_KERNEL);
	if (!config) {
		dev_err(&pdev->dev, "out of memory\n");
		status = -ENOMEM;
		goto err_release_region;
	}

	config->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(config->clk)) {
		status = PTR_ERR(config->clk);
		goto err_kfree;
	}

	status = clk_enable(config->clk);
	if (status < 0)
		goto err_clk_put;

	config->ioaddr = ioremap(res->start, resource_size(res));
	if (!config->ioaddr) {
		dev_err(&pdev->dev, "ioremap fail\n");
		status = -ENOMEM;
		goto err_disable_clock;
	}

	spin_lock_init(&config->lock);
	platform_set_drvdata(pdev, config);

	config->rtc = rtc_device_register(pdev->name, &pdev->dev,
			&spear_rtc_ops, THIS_MODULE);
	if (IS_ERR(config->rtc)) {
		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
				PTR_ERR(config->rtc));
		status = PTR_ERR(config->rtc);
		goto err_iounmap;
	}

	/* alarm irqs */
	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "no update irq?\n");
		status = irq;
		goto err_clear_platdata;
	}

	status = request_irq(irq, spear_rtc_irq, 0, pdev->name, config);
	if (status) {
		dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \
				claimed\n", irq);
		goto err_clear_platdata;
	}

	if (!device_can_wakeup(&pdev->dev))
		device_init_wakeup(&pdev->dev, 1);

	return 0;

err_clear_platdata:
	platform_set_drvdata(pdev, NULL);
	rtc_device_unregister(config->rtc);
err_iounmap:
	iounmap(config->ioaddr);
err_disable_clock:
	clk_disable(config->clk);
err_clk_put:
	clk_put(config->clk);
err_kfree:
	kfree(config);
err_release_region:
	release_mem_region(res->start, resource_size(res));

	return status;
}
示例#24
0
static int __devinit ds1742_rtc_probe(struct platform_device *pdev)
{
	struct rtc_device *rtc;
	struct resource *res;
	unsigned int cen, sec;
	struct rtc_plat_data *pdata = NULL;
	void __iomem *ioaddr = NULL;
	int ret = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;
	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;
	pdata->size = res->end - res->start + 1;
	if (!request_mem_region(res->start, pdata->size, pdev->name)) {
		ret = -EBUSY;
		goto out;
	}
	pdata->baseaddr = res->start;
	ioaddr = ioremap(pdata->baseaddr, pdata->size);
	if (!ioaddr) {
		ret = -ENOMEM;
		goto out;
	}
	pdata->ioaddr_nvram = ioaddr;
	pdata->size_nvram = pdata->size - RTC_SIZE;
	pdata->ioaddr_rtc = ioaddr + pdata->size_nvram;

	pdata->nvram_attr.attr.name = "nvram";
	pdata->nvram_attr.attr.mode = S_IRUGO | S_IWUSR;
	pdata->nvram_attr.read = ds1742_nvram_read;
	pdata->nvram_attr.write = ds1742_nvram_write;
	pdata->nvram_attr.size = pdata->size_nvram;

	/* turn RTC on if it was not on */
	ioaddr = pdata->ioaddr_rtc;
	sec = readb(ioaddr + RTC_SECONDS);
	if (sec & RTC_STOP) {
		sec &= RTC_SECONDS_MASK;
		cen = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
		writeb(RTC_WRITE, ioaddr + RTC_CONTROL);
		writeb(sec, ioaddr + RTC_SECONDS);
		writeb(cen & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
	}
	if (!(readb(ioaddr + RTC_DAY) & RTC_BATT_FLAG))
		dev_warn(&pdev->dev, "voltage-low detected.\n");

	rtc = rtc_device_register(pdev->name, &pdev->dev,
				  &ds1742_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc)) {
		ret = PTR_ERR(rtc);
		goto out;
	}
	pdata->rtc = rtc;
	pdata->last_jiffies = jiffies;
	platform_set_drvdata(pdev, pdata);

	ret = sysfs_create_bin_file(&pdev->dev.kobj, &pdata->nvram_attr);
	if (ret) {
		dev_err(&pdev->dev, "creating nvram file in sysfs failed\n");
		goto out;
	}

	return 0;
 out:
	if (pdata->rtc)
		rtc_device_unregister(pdata->rtc);
	if (pdata->ioaddr_nvram)
		iounmap(pdata->ioaddr_nvram);
	if (pdata->baseaddr)
		release_mem_region(pdata->baseaddr, pdata->size);
	kfree(pdata);
	return ret;
}
static int __devinit fm3130_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	struct fm3130		*fm3130;
	int			err = -ENODEV;
	int			tmp;
	struct i2c_adapter	*adapter = to_i2c_adapter(client->dev.parent);

	if (!i2c_check_functionality(adapter,
			I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
		return -EIO;

	fm3130 = kzalloc(sizeof(struct fm3130), GFP_KERNEL);

	if (!fm3130)
		return -ENOMEM;

	fm3130->client = client;
	i2c_set_clientdata(client, fm3130);
	fm3130->reg_addr_time = FM3130_RTC_SECONDS;
	fm3130->reg_addr_alarm = FM3130_ALARM_SECONDS;

	/* Messages to read time */
	fm3130->msg[0].addr = client->addr;
	fm3130->msg[0].flags = 0;
	fm3130->msg[0].len = 1;
	fm3130->msg[0].buf = &fm3130->reg_addr_time;

	fm3130->msg[1].addr = client->addr;
	fm3130->msg[1].flags = I2C_M_RD;
	fm3130->msg[1].len = FM3130_CLOCK_REGS;
	fm3130->msg[1].buf = &fm3130->regs[FM3130_RTC_SECONDS];

	/* Messages to read alarm */
	fm3130->msg[2].addr = client->addr;
	fm3130->msg[2].flags = 0;
	fm3130->msg[2].len = 1;
	fm3130->msg[2].buf = &fm3130->reg_addr_alarm;

	fm3130->msg[3].addr = client->addr;
	fm3130->msg[3].flags = I2C_M_RD;
	fm3130->msg[3].len = FM3130_ALARM_REGS;
	fm3130->msg[3].buf = &fm3130->regs[FM3130_ALARM_SECONDS];

	fm3130->data_valid = 0;

	tmp = i2c_transfer(adapter, fm3130->msg, 4);
	if (tmp != 4) {
		pr_debug("read error %d\n", tmp);
		err = -EIO;
		goto exit_free;
	}

	fm3130->regs[FM3130_RTC_CONTROL] =
		i2c_smbus_read_byte_data(client, FM3130_RTC_CONTROL);
	fm3130->regs[FM3130_CAL_CONTROL] =
		i2c_smbus_read_byte_data(client, FM3130_CAL_CONTROL);

	/* Checking for alarm */
	if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) {
		fm3130->alarm = 1;
		fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF;
	}

	/* Disabling calibration mode */
	if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_CAL)
		i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL,
			fm3130->regs[FM3130_RTC_CONTROL] &
				~(FM3130_RTC_CONTROL_BIT_CAL));
		dev_warn(&client->dev, "Disabling calibration mode!\n");

	/* Disabling read and write modes */
	if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_WRITE ||
	    fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_READ)
		i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL,
			fm3130->regs[FM3130_RTC_CONTROL] &
				~(FM3130_RTC_CONTROL_BIT_READ |
					FM3130_RTC_CONTROL_BIT_WRITE));
		dev_warn(&client->dev, "Disabling READ or WRITE mode!\n");

	/* oscillator off?  turn it on, so clock can tick. */
	if (fm3130->regs[FM3130_CAL_CONTROL] & FM3130_CAL_CONTROL_BIT_nOSCEN)
		i2c_smbus_write_byte_data(client, FM3130_CAL_CONTROL,
			fm3130->regs[FM3130_CAL_CONTROL] &
				~(FM3130_CAL_CONTROL_BIT_nOSCEN));

	/* oscillator fault?  clear flag, and warn */
	if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_LB)
		dev_warn(&client->dev, "Low battery!\n");

	/* oscillator fault?  clear flag, and warn */
	if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_POR) {
		i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL,
			fm3130->regs[FM3130_RTC_CONTROL] &
				~FM3130_RTC_CONTROL_BIT_POR);
		dev_warn(&client->dev, "SET TIME!\n");
	}
	/* ACS is controlled by alarm */
	i2c_smbus_write_byte_data(client, FM3130_ALARM_WP_CONTROL, 0x80);

	/* TODO */
	/* TODO need to sanity check alarm */
	tmp = fm3130->regs[FM3130_RTC_SECONDS];
	tmp = bcd2bin(tmp & 0x7f);
	if (tmp > 60)
		goto exit_bad;
	tmp = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f);
	if (tmp > 60)
		goto exit_bad;

	tmp = bcd2bin(fm3130->regs[FM3130_RTC_DATE] & 0x3f);
	if (tmp == 0 || tmp > 31)
		goto exit_bad;

	tmp = bcd2bin(fm3130->regs[FM3130_RTC_MONTHS] & 0x1f);
	if (tmp == 0 || tmp > 12)
		goto exit_bad;

	tmp = fm3130->regs[FM3130_RTC_HOURS];

	fm3130->data_valid = 1;

exit_bad:
	if (!fm3130->data_valid)
		dev_dbg(&client->dev,
				"%s: %02x %02x %02x %02x %02x %02x %02x %02x"
				"%02x %02x %02x %02x %02x %02x %02x\n",
			"bogus registers",
			fm3130->regs[0], fm3130->regs[1],
			fm3130->regs[2], fm3130->regs[3],
			fm3130->regs[4], fm3130->regs[5],
			fm3130->regs[6], fm3130->regs[7],
			fm3130->regs[8], fm3130->regs[9],
			fm3130->regs[0xa], fm3130->regs[0xb],
			fm3130->regs[0xc], fm3130->regs[0xd],
			fm3130->regs[0xe]);

	/* We won't bail out here because we just got invalid data.
	   Time setting from u-boot doesn't work anyway */
	fm3130->rtc = rtc_device_register(client->name, &client->dev,
				&fm3130_rtc_ops, THIS_MODULE);
	if (IS_ERR(fm3130->rtc)) {
		err = PTR_ERR(fm3130->rtc);
		dev_err(&client->dev,
			"unable to register the class device\n");
		goto exit_free;
	}
	return 0;
exit_free:
	kfree(fm3130);
	return err;
}
示例#26
0
static int __devinit stm_rtc_probe(struct platform_device *pdev)
{
	struct stm_plat_rtc_lpc *plat_data;
	struct stm_rtc *rtc;
	struct resource *res;
	int size;
	int ret = 0;
	struct rtc_time tm_check;

	rtc = kzalloc(sizeof(struct stm_rtc), GFP_KERNEL);
	if (unlikely(!rtc))
		return -ENOMEM;

	spin_lock_init(&rtc->lock);
	plat_data = pdev->dev.platform_data;
	if (unlikely(plat_data == NULL)) {
		dev_err(&pdev->dev, "No platform data\n");
		ret = -ENOENT;
		goto err_badres;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(res == NULL)) {
		dev_err(&pdev->dev, "No IO resource\n");
		ret = -ENOENT;
		goto err_badres;
	}

	size = res->end - res->start + 1;
	rtc->res = request_mem_region(res->start, size, pdev->name);
	if (!rtc->res) {
		ret = -EBUSY;
		goto err_badres;
	}

	rtc->ioaddr = ioremap_nocache(res->start, size);
	if (!rtc->ioaddr) {
		ret = -EINVAL;
		goto err_badmap;
	}

	if (plat_data->clk_id)
		rtc->clk = clk_get(&pdev->dev, plat_data->clk_id);
	else
		rtc->clk = clk_get(&pdev->dev, "lpc_clk");
	if (IS_ERR(rtc->clk)) {
		pr_err("clk lpc_clk not found\n");
		ret = PTR_ERR(rtc->clk);
		goto err_badreg;
	}
	clk_enable(rtc->clk);

	if (plat_data->force_clk_rate)
		clk_set_rate(rtc->clk, plat_data->force_clk_rate);

	pr_debug("%s: is using clk: %s @ %lu\n",
		DRV_NAME, rtc->clk->name, clk_get_rate(rtc->clk));

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		pr_err("%s Request irq %d not done\n",
			__func__, res->start);
		return -ENODEV;
	}

	rtc->irq = res->start;
	irq_set_irq_type(rtc->irq, plat_data->irq_edge_level);
	enable_irq_wake(rtc->irq);
	if (devm_request_irq(&pdev->dev, rtc->irq, stm_rtc_irq,
		IRQF_DISABLED, DRV_NAME, rtc) < 0){
		pr_err("%s: Request irq not done\n", __func__);
		return -ENODEV;
	}
	disable_irq(rtc->irq);

	device_set_wakeup_capable(&pdev->dev, 1);

	platform_set_drvdata(pdev, rtc);

	/*
	 * The RTC-LPC is able to manage date.year > 2038
	 * but currently the kernel can not manage this date!
	 * If the RTC-LPC has a date.year > 2038 then
	 * it's set to the epoch "Jan 1st 2000"
	 */
	stm_rtc_read_time(&pdev->dev, &tm_check);

	if (tm_check.tm_year >=  (2038 - 1900)) {
		memset(&tm_check, 0, sizeof(tm_check));
		tm_check.tm_year = 100;
		/*
		 * FIXME:
		 *   the 'tm_check.tm_mday' should be set to zero but the func-
		 *   tions rtc_tm_to_time and rtc_time_to_time aren't coherent.
		 */
		tm_check.tm_mday = 1;
		stm_rtc_set_time(&pdev->dev, &tm_check);
	}

	rtc->rtc_dev = rtc_device_register(DRV_NAME, &pdev->dev,
					   &stm_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc->rtc_dev)) {
		ret = PTR_ERR(rtc->rtc_dev);
		goto err_badreg;
	}

	return ret;

err_badreg:
	iounmap(rtc->ioaddr);
err_badmap:
	release_resource(rtc->res);
err_badres:
	kfree(rtc);

	platform_set_drvdata(pdev, NULL);
	return ret;
}
static int __devinit sunxi_rtc_probe(struct platform_device *pdev)
{
	struct rtc_device *rtc;	
	int ret;
	unsigned int tmp_data;
	
#ifdef BACKUP_PWM
	unsigned int pwm_ctrl_reg_backup = 0;
	unsigned int pwm_ch0_period_backup = 0;
#endif
		
	sunxi_rtc_base = (void __iomem *)(SW_VA_TIMERC_IO_BASE);
	sunxi_rtc_alarmno = SW_INT_IRQNO_ALARM;
		
	/* select RTC clock source
	*  on fpga board, internal 32k clk src is the default, and can not be changed
	*
	*  RTC CLOCK SOURCE internal 32K HZ 
	*/
#ifdef BACKUP_PWM
	pwm_ctrl_reg_backup = readl(PWM_CTRL_REG_BASE + 0);
	pwm_ch0_period_backup = readl(PWM_CTRL_REG_BASE + 4);
	printk("[rtc-pwm] 1 pwm_ctrl_reg_backup = %x pwm_ch0_period_backup = %x", pwm_ctrl_reg_backup, pwm_ch0_period_backup);
#endif
	
	/*	upate by kevin, 2011-9-7 18:23
	*	step1: set keyfiled,选择外部晶振
	*/
	tmp_data = readl(sunxi_rtc_base + SUNXI_LOSC_CTRL_REG); 
	tmp_data &= (~REG_CLK32K_AUTO_SWT_EN);            		//disable auto switch,bit-14
	tmp_data |= (RTC_SOURCE_EXTERNAL | REG_LOSCCTRL_MAGIC); //external     32768hz osc
	tmp_data |= (EXT_LOSC_GSM);                             //external 32768hz osc gsm
	writel(tmp_data, sunxi_rtc_base + SUNXI_LOSC_CTRL_REG);
	__udelay(100);
	_dev_info(&(pdev->dev),"sunxi_rtc_probe tmp_data = %d\n", tmp_data);
	
	/*step2: check set result,查询是否设置成功*/
	tmp_data = readl(sunxi_rtc_base + SUNXI_LOSC_CTRL_REG);
	if(!(tmp_data & RTC_SOURCE_EXTERNAL)){
		printk("[RTC] ERR: Set LOSC to external failed!!!\n");
		printk("[RTC] WARNING: Rtc time will be wrong!!\n");
		losc_err_flag = 1;
	}
	
#ifdef BACKUP_PWM
	writel(pwm_ctrl_reg_backup, PWM_CTRL_REG_BASE + 0);
	writel(pwm_ch0_period_backup, PWM_CTRL_REG_BASE + 4);
	pwm_ctrl_reg_backup = readl(PWM_CTRL_REG_BASE + 0);
	pwm_ch0_period_backup = readl(PWM_CTRL_REG_BASE + 4);
	printk("[rtc-pwm] 2 pwm_ctrl_reg_backup = %x pwm_ch0_period_backup = %x", pwm_ctrl_reg_backup, pwm_ch0_period_backup);
#endif
	
	device_init_wakeup(&pdev->dev, 1);
	
	/* register RTC and exit */
	rtc = rtc_device_register("rtc", &pdev->dev, &sunxi_rtcops, THIS_MODULE);
	if (IS_ERR(rtc)) {
		dev_err(&pdev->dev, "cannot attach rtc\n");
		ret = PTR_ERR(rtc);
		goto err_out;
	}
	ret = request_irq(sunxi_rtc_alarmno, sunxi_rtc_alarmirq,
			  IRQF_DISABLED,  "sunxi-rtc alarm", rtc);
	if (ret) {
		dev_err(&pdev->dev, "IRQ%d error %d\n", sunxi_rtc_alarmno, ret);
		rtc_device_unregister(rtc);
		return ret;
	}

	sw_rtc_dev = rtc;
	platform_set_drvdata(pdev, rtc);//设置rtc结构数据为pdev的私有数据
	
	return 0;
	
	err_out:
		return ret;
}
static int
vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
{
	int retval = 0;
	unsigned char rtc_control;
	unsigned char enable_bit_save = 0;

	/* There can be only one ... */
	if (mrst_rtc.dev)
		return -EBUSY;

	if (!iomem)
		return -ENODEV;

	iomem = request_mem_region(iomem->start,
			iomem->end + 1 - iomem->start,
			driver_name);
	if (!iomem) {
		dev_dbg(dev, "i/o mem already in use.\n");
		return -EBUSY;
	}

	mrst_rtc.irq = rtc_irq;
	mrst_rtc.iomem = iomem;
	mrst_rtc.dev = dev;
	dev_set_drvdata(dev, &mrst_rtc);

	mrst_rtc.rtc = rtc_device_register(driver_name, dev,
				&mrst_rtc_ops, THIS_MODULE);
	if (IS_ERR(mrst_rtc.rtc)) {
		retval = PTR_ERR(mrst_rtc.rtc);
		goto cleanup0;
	}

	rename_region(iomem, dev_name(&mrst_rtc.rtc->dev));

	printk(KERN_ALERT"(%s) +------------rtc info-----------+\n",__func__);
	spin_lock_irq(&rtc_lock);
	enable_bit_save = vrtc_cmos_read(RTC_CONTROL);
	enable_bit_save &= (RTC_PIE | RTC_AIE);
	mrst_irq_disable(&mrst_rtc, RTC_PIE | RTC_AIE);
	rtc_control = vrtc_cmos_read(RTC_CONTROL);
	spin_unlock_irq(&rtc_lock);
	printk(KERN_ALERT"read PIE_AIE_save = 0x%02x, then clear. rtc_control = 0x%02x\n",enable_bit_save,rtc_control);

	if (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))
		dev_dbg(dev, "TODO: support more than 24-hr BCD mode\n");

	if (is_valid_irq(rtc_irq)) {
		retval = request_irq(rtc_irq, mrst_rtc_irq,
				IRQF_NO_SUSPEND, dev_name(&mrst_rtc.rtc->dev),
				mrst_rtc.rtc);
		if (retval < 0) {
			dev_dbg(dev, "IRQ %d is already in use, err %d\n",
				rtc_irq, retval);
			goto cleanup1;
		}
	}

	/* make RTC device wake capable from sleep */
	device_init_wakeup(dev, true);

	if ((__intel_mid_cpu_chip == INTEL_MID_CPU_CHIP_PENWELL) ||
	    (__intel_mid_cpu_chip == INTEL_MID_CPU_CHIP_CLOVERVIEW)) {
		retval = rpmsg_send_command(vrtc_mrst_instance,
				IPCMSG_GET_HOBADDR, 0, NULL, &oshob_base, 0, 1);
		if (retval < 0) {
			dev_dbg(dev,
				"Unable to get OSHOB base address, err %d\n",
				retval);
			goto cleanup1;
		}

		oshob_addr = ioremap_nocache(oshob_base+OSHOB_ALARM_OFFSET, 4);
		if (!oshob_addr) {
			dev_dbg(dev, "Unable to do ioremap for OSHOB\n");
			retval = -ENOMEM;
			goto cleanup1;
		}
	}

	spin_lock_irq(&rtc_lock);
	if(enable_bit_save)
		mrst_irq_enable(&mrst_rtc, enable_bit_save);//add for power off rtc issue
	spin_unlock_irq(&rtc_lock);
	rtc_control = vrtc_cmos_read(RTC_CONTROL);
	printk(KERN_ALERT"read resume rtc_control = 0x%02x.\n",rtc_control);
	printk(KERN_ALERT"(%s) +-------------------------------+\n",__func__);
	dev_dbg(dev, "vRTC driver initialised\n");
	return 0;

cleanup1:
	rtc_device_unregister(mrst_rtc.rtc);
cleanup0:
	dev_set_drvdata(dev, NULL);
	mrst_rtc.dev = NULL;
	release_mem_region(iomem->start, resource_size(iomem));
	dev_err(dev, "rtc-mrst: unable to initialise\n");
	return retval;
}
示例#29
0
static int s3c_rtc_probe(struct platform_device *pdev)
{
	struct rtc_device *rtc;
	struct resource *res;
	int ret;

	pr_debug("%s: probe=%p\n", __FUNCTION__, 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(s3c_rtc_freq);

	/* 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 = 128;

	platform_set_drvdata(pdev, rtc);
	return 0;

 err_nortc:
	s3c_rtc_enable(pdev, 0);
	iounmap(s3c_rtc_base);

 err_nomap:
	release_resource(s3c_rtc_mem);

 err_nores:
	return ret;
}
static int __devinit pcf2123_probe(struct spi_device *spi)
{
	struct rtc_device *rtc;
	struct pcf2123_plat_data *pdata;
	u8 txbuf[2], rxbuf[2];
	int ret, i;

	pdata = kzalloc(sizeof(struct pcf2123_plat_data), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;
	spi->dev.platform_data = pdata;

	/*                               */
	txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1;
	txbuf[1] = 0x58;
	dev_dbg(&spi->dev, "resetting RTC (0x%02X 0x%02X)\n",
			txbuf[0], txbuf[1]);
	ret = spi_write(spi, txbuf, 2 * sizeof(u8));
	if (ret < 0)
		goto kfree_exit;
	pcf2123_delay_trec();

	/*                  */
	txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1;
	txbuf[1] = 0x20;
	dev_dbg(&spi->dev, "stopping RTC (0x%02X 0x%02X)\n",
			txbuf[0], txbuf[1]);
	ret = spi_write(spi, txbuf, 2 * sizeof(u8));
	if (ret < 0)
		goto kfree_exit;
	pcf2123_delay_trec();

	/*                                         */
	txbuf[0] = PCF2123_READ | PCF2123_REG_CTRL1;
	dev_dbg(&spi->dev, "checking for presence of RTC (0x%02X)\n",
			txbuf[0]);
	ret = spi_write_then_read(spi, txbuf, 1 * sizeof(u8),
					rxbuf, 2 * sizeof(u8));
	dev_dbg(&spi->dev, "received data from RTC (0x%02X 0x%02X)\n",
			rxbuf[0], rxbuf[1]);
	if (ret < 0)
		goto kfree_exit;
	pcf2123_delay_trec();

	if (!(rxbuf[0] & 0x20)) {
		dev_err(&spi->dev, "chip not found\n");
		goto kfree_exit;
	}

	dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n");
	dev_info(&spi->dev, "spiclk %u KHz.\n",
			(spi->max_speed_hz + 500) / 1000);

	/*                   */
	txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1;
	txbuf[1] = 0x00;
	ret = spi_write(spi, txbuf, sizeof(txbuf));
	if (ret < 0)
		goto kfree_exit;
	pcf2123_delay_trec();

	/*                             */
	rtc = rtc_device_register(pcf2123_driver.driver.name, &spi->dev,
			&pcf2123_rtc_ops, THIS_MODULE);

	if (IS_ERR(rtc)) {
		dev_err(&spi->dev, "failed to register.\n");
		ret = PTR_ERR(rtc);
		goto kfree_exit;
	}

	pdata->rtc = rtc;

	for (i = 0; i < 16; i++) {
		sprintf(pdata->regs[i].name, "%1x", i);
		pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR;
		pdata->regs[i].attr.attr.name = pdata->regs[i].name;
		pdata->regs[i].attr.show = pcf2123_show;
		pdata->regs[i].attr.store = pcf2123_store;
		ret = device_create_file(&spi->dev, &pdata->regs[i].attr);
		if (ret) {
			dev_err(&spi->dev, "Unable to create sysfs %s\n",
				pdata->regs[i].name);
			goto sysfs_exit;
		}
	}

	return 0;

sysfs_exit:
	for (i--; i >= 0; i--)
		device_remove_file(&spi->dev, &pdata->regs[i].attr);

kfree_exit:
	kfree(pdata);
	spi->dev.platform_data = NULL;
	return ret;
}