diff options
Diffstat (limited to 'drivers/rtc/rtc-at91sam9.c')
| -rw-r--r-- | drivers/rtc/rtc-at91sam9.c | 85 | 
1 files changed, 28 insertions, 57 deletions
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 274a0aafe42..831868904e0 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -57,6 +57,7 @@ struct sam9_rtc {  	void __iomem		*rtt;  	struct rtc_device	*rtcdev;  	u32			imr; +	void __iomem		*gpbr;  };  #define rtt_readl(rtc, field) \ @@ -65,9 +66,9 @@ struct sam9_rtc {  	__raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field)  #define gpbr_readl(rtc) \ -	at91_sys_read(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR) +	__raw_readl((rtc)->gpbr)  #define gpbr_writel(rtc, val) \ -	at91_sys_write(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR, (val)) +	__raw_writel((val), (rtc)->gpbr)  /*   * Read current time and date in RTC @@ -287,16 +288,19 @@ static const struct rtc_class_ops at91_rtc_ops = {  /*   * Initialize and install RTC driver   */ -static int __init at91_rtc_probe(struct platform_device *pdev) +static int __devinit at91_rtc_probe(struct platform_device *pdev)  { -	struct resource	*r; +	struct resource	*r, *r_gpbr;  	struct sam9_rtc	*rtc;  	int		ret;  	u32		mr;  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!r) +	r_gpbr = platform_get_resource(pdev, IORESOURCE_MEM, 1); +	if (!r || !r_gpbr) { +		dev_err(&pdev->dev, "need 2 ressources\n");  		return -ENODEV; +	}  	rtc = kzalloc(sizeof *rtc, GFP_KERNEL);  	if (!rtc) @@ -314,6 +318,13 @@ static int __init at91_rtc_probe(struct platform_device *pdev)  		goto fail;  	} +	rtc->gpbr = ioremap(r_gpbr->start, resource_size(r_gpbr)); +	if (!rtc->gpbr) { +		dev_err(&pdev->dev, "failed to map gpbr registers, aborting.\n"); +		ret = -ENOMEM; +		goto fail_gpbr; +	} +  	mr = rtt_readl(rtc, MR);  	/* unless RTT is counting at 1 Hz, re-initialize it */ @@ -340,7 +351,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)  	if (ret) {  		dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);  		rtc_device_unregister(rtc->rtcdev); -		goto fail; +		goto fail_register;  	}  	/* NOTE:  sam9260 rev A silicon has a ROM bug which resets the @@ -356,6 +367,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev)  	return 0;  fail_register: +	iounmap(rtc->gpbr); +fail_gpbr:  	iounmap(rtc->rtt);  fail:  	platform_set_drvdata(pdev, NULL); @@ -366,7 +379,7 @@ fail:  /*   * Disable and remove the RTC driver   */ -static int __exit at91_rtc_remove(struct platform_device *pdev) +static int __devexit at91_rtc_remove(struct platform_device *pdev)  {  	struct sam9_rtc	*rtc = platform_get_drvdata(pdev);  	u32		mr = rtt_readl(rtc, MR); @@ -377,6 +390,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)  	rtc_device_unregister(rtc->rtcdev); +	iounmap(rtc->gpbr);  	iounmap(rtc->rtt);  	platform_set_drvdata(pdev, NULL);  	kfree(rtc); @@ -440,63 +454,20 @@ static int at91_rtc_resume(struct platform_device *pdev)  #endif  static struct platform_driver at91_rtc_driver = { -	.driver.name	= "rtc-at91sam9", -	.driver.owner	= THIS_MODULE, -	.remove		= __exit_p(at91_rtc_remove), +	.probe		= at91_rtc_probe, +	.remove		= __devexit_p(at91_rtc_remove),  	.shutdown	= at91_rtc_shutdown,  	.suspend	= at91_rtc_suspend,  	.resume		= at91_rtc_resume, +	.driver		= { +		.name	= "rtc-at91sam9", +		.owner	= THIS_MODULE, +	},  }; -/* Chips can have more than one RTT module, and they can be used for more - * than just RTCs.  So we can't just register as "the" RTT driver. - * - * A normal approach in such cases is to create a library to allocate and - * free the modules.  Here we just use bus_find_device() as like such a - * library, binding directly ... no runtime "library" footprint is needed. - */ -static int __init at91_rtc_match(struct device *dev, void *v) -{ -	struct platform_device *pdev = to_platform_device(dev); -	int ret; - -	/* continue searching if this isn't the RTT we need */ -	if (strcmp("at91_rtt", pdev->name) != 0 -			|| pdev->id != CONFIG_RTC_DRV_AT91SAM9_RTT) -		goto fail; - -	/* else we found it ... but fail unless we can bind to the RTC driver */ -	if (dev->driver) { -		dev_dbg(dev, "busy, can't use as RTC!\n"); -		goto fail; -	} -	dev->driver = &at91_rtc_driver.driver; -	if (device_attach(dev) == 0) { -		dev_dbg(dev, "can't attach RTC!\n"); -		goto fail; -	} -	ret = at91_rtc_probe(pdev); -	if (ret == 0) -		return true; - -	dev_dbg(dev, "RTC probe err %d!\n", ret); -fail: -	return false; -} -  static int __init at91_rtc_init(void)  { -	int status; -	struct device *rtc; - -	status = platform_driver_register(&at91_rtc_driver); -	if (status) -		return status; -	rtc = bus_find_device(&platform_bus_type, NULL, -			NULL, at91_rtc_match); -	if (!rtc) -		platform_driver_unregister(&at91_rtc_driver); -	return rtc ? 0 : -ENODEV; +	return platform_driver_register(&at91_rtc_driver);  }  module_init(at91_rtc_init);  |