diff options
Diffstat (limited to 'drivers/rtc/rtc-ds1305.c')
| -rw-r--r-- | drivers/rtc/rtc-ds1305.c | 146 | 
1 files changed, 51 insertions, 95 deletions
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 48da85e97ca..129add77065 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -17,6 +17,7 @@  #include <linux/spi/spi.h>  #include <linux/spi/ds1305.h> +#include <linux/module.h>  /* @@ -139,49 +140,32 @@ static u8 hour2bcd(bool hr12, int hour)   * Interface to RTC framework   */ -#ifdef CONFIG_RTC_INTF_DEV - -/* - * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) - */ -static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg) +static int ds1305_alarm_irq_enable(struct device *dev, unsigned int enabled)  {  	struct ds1305	*ds1305 = dev_get_drvdata(dev);  	u8		buf[2]; -	int		status = -ENOIOCTLCMD; +	long		err = -EINVAL;  	buf[0] = DS1305_WRITE | DS1305_CONTROL;  	buf[1] = ds1305->ctrl[0]; -	switch (cmd) { -	case RTC_AIE_OFF: -		status = 0; -		if (!(buf[1] & DS1305_AEI0)) -			goto done; -		buf[1] &= ~DS1305_AEI0; -		break; - -	case RTC_AIE_ON: -		status = 0; +	if (enabled) {  		if (ds1305->ctrl[0] & DS1305_AEI0)  			goto done;  		buf[1] |= DS1305_AEI0; -		break; -	} -	if (status == 0) { -		status = spi_write_then_read(ds1305->spi, buf, sizeof buf, -				NULL, 0); -		if (status >= 0) -			ds1305->ctrl[0] = buf[1]; +	} else { +		if (!(buf[1] & DS1305_AEI0)) +			goto done; +		buf[1] &= ~DS1305_AEI0;  	} - +	err = spi_write_then_read(ds1305->spi, buf, sizeof(buf), NULL, 0); +	if (err >= 0) +		ds1305->ctrl[0] = buf[1];  done: -	return status; +	return err; +  } -#else -#define ds1305_ioctl	NULL -#endif  /*   * Get/set of date and time is pretty normal. @@ -197,8 +181,8 @@ static int ds1305_get_time(struct device *dev, struct rtc_time *time)  	/* Use write-then-read to get all the date/time registers  	 * since dma from stack is nonportable  	 */ -	status = spi_write_then_read(ds1305->spi, &addr, sizeof addr, -			buf, sizeof buf); +	status = spi_write_then_read(ds1305->spi, &addr, sizeof(addr), +			buf, sizeof(buf));  	if (status < 0)  		return status; @@ -253,7 +237,7 @@ static int ds1305_set_time(struct device *dev, struct rtc_time *time)  		buf[4], buf[5], buf[6], buf[7]);  	/* use write-then-read since dma from stack is nonportable */ -	return spi_write_then_read(ds1305->spi, buf, sizeof buf, +	return spi_write_then_read(ds1305->spi, buf, sizeof(buf),  			NULL, 0);  } @@ -302,8 +286,8 @@ static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm)  	 * of EFI status is at best fragile anyway (given IRQ handlers).  	 */  	addr = DS1305_CONTROL; -	status = spi_write_then_read(spi, &addr, sizeof addr, -			ds1305->ctrl, sizeof ds1305->ctrl); +	status = spi_write_then_read(spi, &addr, sizeof(addr), +			ds1305->ctrl, sizeof(ds1305->ctrl));  	if (status < 0)  		return status; @@ -312,8 +296,8 @@ static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm)  	/* get and check ALM0 registers */  	addr = DS1305_ALM0(DS1305_SEC); -	status = spi_write_then_read(spi, &addr, sizeof addr, -			buf, sizeof buf); +	status = spi_write_then_read(spi, &addr, sizeof(addr), +			buf, sizeof(buf));  	if (status < 0)  		return status; @@ -397,7 +381,7 @@ static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm)  		"alm0 write", buf[1 + DS1305_SEC], buf[1 + DS1305_MIN],  		buf[1 + DS1305_HOUR], buf[1 + DS1305_WDAY]); -	status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); +	status = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);  	if (status < 0)  		return status; @@ -460,12 +444,12 @@ done:  #endif  static const struct rtc_class_ops ds1305_ops = { -	.ioctl		= ds1305_ioctl,  	.read_time	= ds1305_get_time,  	.set_time	= ds1305_set_time,  	.read_alarm	= ds1305_get_alarm,  	.set_alarm	= ds1305_set_alarm,  	.proc		= ds1305_proc, +	.alarm_irq_enable = ds1305_alarm_irq_enable,  };  static void ds1305_work(struct work_struct *work) @@ -490,7 +474,7 @@ static void ds1305_work(struct work_struct *work)  	buf[1] = ds1305->ctrl[0];  	buf[2] = 0; -	status = spi_write_then_read(spi, buf, sizeof buf, +	status = spi_write_then_read(spi, buf, sizeof(buf),  			NULL, 0);  	if (status < 0)  		dev_dbg(&spi->dev, "clear irq --> %d\n", status); @@ -617,12 +601,12 @@ static struct bin_attribute nvram = {   * Interface to SPI stack   */ -static int __devinit ds1305_probe(struct spi_device *spi) +static int ds1305_probe(struct spi_device *spi)  {  	struct ds1305			*ds1305;  	int				status;  	u8				addr, value; -	struct ds1305_platform_data	*pdata = spi->dev.platform_data; +	struct ds1305_platform_data	*pdata = dev_get_platdata(&spi->dev);  	bool				write_ctrl = false;  	/* Sanity check board setup data.  This may be hooked up @@ -635,7 +619,7 @@ static int __devinit ds1305_probe(struct spi_device *spi)  		return -EINVAL;  	/* set up driver data */ -	ds1305 = kzalloc(sizeof *ds1305, GFP_KERNEL); +	ds1305 = devm_kzalloc(&spi->dev, sizeof(*ds1305), GFP_KERNEL);  	if (!ds1305)  		return -ENOMEM;  	ds1305->spi = spi; @@ -643,17 +627,15 @@ static int __devinit ds1305_probe(struct spi_device *spi)  	/* read and cache control registers */  	addr = DS1305_CONTROL; -	status = spi_write_then_read(spi, &addr, sizeof addr, -			ds1305->ctrl, sizeof ds1305->ctrl); +	status = spi_write_then_read(spi, &addr, sizeof(addr), +			ds1305->ctrl, sizeof(ds1305->ctrl));  	if (status < 0) {  		dev_dbg(&spi->dev, "can't %s, %d\n",  				"read", status); -		goto fail0; +		return status;  	} -	dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", -			"read", ds1305->ctrl[0], -			ds1305->ctrl[1], ds1305->ctrl[2]); +	dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "read", ds1305->ctrl);  	/* Sanity check register values ... partially compensating for the  	 * fact that SPI has no device handshake.  A pullup on MISO would @@ -662,8 +644,7 @@ static int __devinit ds1305_probe(struct spi_device *spi)  	 */  	if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) {  		dev_dbg(&spi->dev, "RTC chip is not present\n"); -		status = -ENODEV; -		goto fail0; +		return -ENODEV;  	}  	if (ds1305->ctrl[2] == 0)  		dev_dbg(&spi->dev, "chip may not be present\n"); @@ -678,11 +659,11 @@ static int __devinit ds1305_probe(struct spi_device *spi)  		buf[0] = DS1305_WRITE | DS1305_CONTROL;  		buf[1] = ds1305->ctrl[0]; -		status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); +		status = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);  		dev_dbg(&spi->dev, "clear WP --> %d\n", status);  		if (status < 0) -			goto fail0; +			return status;  	}  	/* on DS1305, maybe start oscillator; like most low power @@ -732,25 +713,23 @@ static int __devinit ds1305_probe(struct spi_device *spi)  		buf[1] = ds1305->ctrl[0];  		buf[2] = ds1305->ctrl[1];  		buf[3] = ds1305->ctrl[2]; -		status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); +		status = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);  		if (status < 0) {  			dev_dbg(&spi->dev, "can't %s, %d\n",  					"write", status); -			goto fail0; +			return status;  		} -		dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", -				"write", ds1305->ctrl[0], -				ds1305->ctrl[1], ds1305->ctrl[2]); +		dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "write", ds1305->ctrl);  	}  	/* see if non-Linux software set up AM/PM mode */  	addr = DS1305_HOUR; -	status = spi_write_then_read(spi, &addr, sizeof addr, -				&value, sizeof value); +	status = spi_write_then_read(spi, &addr, sizeof(addr), +				&value, sizeof(value));  	if (status < 0) {  		dev_dbg(&spi->dev, "read HOUR --> %d\n", status); -		goto fail0; +		return status;  	}  	ds1305->hr12 = (DS1305_HR_12 & value) != 0; @@ -758,12 +737,12 @@ static int __devinit ds1305_probe(struct spi_device *spi)  		dev_dbg(&spi->dev, "AM/PM\n");  	/* register RTC ... from here on, ds1305->ctrl needs locking */ -	ds1305->rtc = rtc_device_register("ds1305", &spi->dev, +	ds1305->rtc = devm_rtc_device_register(&spi->dev, "ds1305",  			&ds1305_ops, THIS_MODULE);  	if (IS_ERR(ds1305->rtc)) {  		status = PTR_ERR(ds1305->rtc);  		dev_dbg(&spi->dev, "register rtc --> %d\n", status); -		goto fail0; +		return status;  	}  	/* Maybe set up alarm IRQ; be ready to handle it triggering right @@ -774,36 +753,26 @@ static int __devinit ds1305_probe(struct spi_device *spi)  	 */  	if (spi->irq) {  		INIT_WORK(&ds1305->work, ds1305_work); -		status = request_irq(spi->irq, ds1305_irq, +		status = devm_request_irq(&spi->dev, spi->irq, ds1305_irq,  				0, dev_name(&ds1305->rtc->dev), ds1305);  		if (status < 0) { -			dev_dbg(&spi->dev, "request_irq %d --> %d\n", +			dev_err(&spi->dev, "request_irq %d --> %d\n",  					spi->irq, status); -			goto fail1; +		} else { +			device_set_wakeup_capable(&spi->dev, 1);  		} - -		device_set_wakeup_capable(&spi->dev, 1);  	}  	/* export NVRAM */  	status = sysfs_create_bin_file(&spi->dev.kobj, &nvram);  	if (status < 0) { -		dev_dbg(&spi->dev, "register nvram --> %d\n", status); -		goto fail2; +		dev_err(&spi->dev, "register nvram --> %d\n", status);  	}  	return 0; - -fail2: -	free_irq(spi->irq, ds1305); -fail1: -	rtc_device_unregister(ds1305->rtc); -fail0: -	kfree(ds1305); -	return status;  } -static int __devexit ds1305_remove(struct spi_device *spi) +static int ds1305_remove(struct spi_device *spi)  {  	struct ds1305 *ds1305 = spi_get_drvdata(spi); @@ -812,13 +781,10 @@ static int __devexit ds1305_remove(struct spi_device *spi)  	/* carefully shut down irq and workqueue, if present */  	if (spi->irq) {  		set_bit(FLAG_EXITING, &ds1305->flags); -		free_irq(spi->irq, ds1305); -		flush_scheduled_work(); +		devm_free_irq(&spi->dev, spi->irq, ds1305); +		cancel_work_sync(&ds1305->work);  	} -	rtc_device_unregister(ds1305->rtc); -	spi_set_drvdata(spi, NULL); -	kfree(ds1305);  	return 0;  } @@ -826,21 +792,11 @@ static struct spi_driver ds1305_driver = {  	.driver.name	= "rtc-ds1305",  	.driver.owner	= THIS_MODULE,  	.probe		= ds1305_probe, -	.remove		= __devexit_p(ds1305_remove), +	.remove		= ds1305_remove,  	/* REVISIT add suspend/resume */  }; -static int __init ds1305_init(void) -{ -	return spi_register_driver(&ds1305_driver); -} -module_init(ds1305_init); - -static void __exit ds1305_exit(void) -{ -	spi_unregister_driver(&ds1305_driver); -} -module_exit(ds1305_exit); +module_spi_driver(ds1305_driver);  MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips");  MODULE_LICENSE("GPL");  | 
