18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Setup code for PC-style Real-Time Clock.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Author: Wade Farnsworth <wfarnsworth@mvista.com>
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * 2007 (c) MontaVista Software, Inc. This file is licensed under
78c2ecf20Sopenharmony_ci * the terms of the GNU General Public License version 2. This program
88c2ecf20Sopenharmony_ci * is licensed "as is" without any warranty of any kind, whether express
98c2ecf20Sopenharmony_ci * or implied.
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
138c2ecf20Sopenharmony_ci#include <linux/err.h>
148c2ecf20Sopenharmony_ci#include <linux/init.h>
158c2ecf20Sopenharmony_ci#include <linux/module.h>
168c2ecf20Sopenharmony_ci#include <linux/mc146818rtc.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include <asm/prom.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistatic int  __init add_rtc(void)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	struct device_node *np;
238c2ecf20Sopenharmony_ci	struct platform_device *pd;
248c2ecf20Sopenharmony_ci	struct resource res[2];
258c2ecf20Sopenharmony_ci	unsigned int num_res = 1;
268c2ecf20Sopenharmony_ci	int ret;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	memset(&res, 0, sizeof(res));
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	np = of_find_compatible_node(NULL, NULL, "pnpPNP,b00");
318c2ecf20Sopenharmony_ci	if (!np)
328c2ecf20Sopenharmony_ci		return -ENODEV;
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	ret = of_address_to_resource(np, 0, &res[0]);
358c2ecf20Sopenharmony_ci	of_node_put(np);
368c2ecf20Sopenharmony_ci	if (ret)
378c2ecf20Sopenharmony_ci		return ret;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	/*
408c2ecf20Sopenharmony_ci	 * RTC_PORT(x) is hardcoded in asm/mc146818rtc.h.  Verify that the
418c2ecf20Sopenharmony_ci	 * address provided by the device node matches.
428c2ecf20Sopenharmony_ci	 */
438c2ecf20Sopenharmony_ci	if (res[0].start != RTC_PORT(0))
448c2ecf20Sopenharmony_ci		return -EINVAL;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	np = of_find_compatible_node(NULL, NULL, "chrp,iic");
478c2ecf20Sopenharmony_ci	if (!np)
488c2ecf20Sopenharmony_ci		np = of_find_compatible_node(NULL, NULL, "pnpPNP,000");
498c2ecf20Sopenharmony_ci	if (np) {
508c2ecf20Sopenharmony_ci		of_node_put(np);
518c2ecf20Sopenharmony_ci		/*
528c2ecf20Sopenharmony_ci		 * Use a fixed interrupt value of 8 since on PPC if we are
538c2ecf20Sopenharmony_ci		 * using this its off an i8259 which we ensure has interrupt
548c2ecf20Sopenharmony_ci		 * numbers 0..15.
558c2ecf20Sopenharmony_ci		 */
568c2ecf20Sopenharmony_ci		res[1].start = 8;
578c2ecf20Sopenharmony_ci		res[1].end = 8;
588c2ecf20Sopenharmony_ci		res[1].flags = IORESOURCE_IRQ;
598c2ecf20Sopenharmony_ci		num_res++;
608c2ecf20Sopenharmony_ci	}
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	pd = platform_device_register_simple("rtc_cmos", -1,
638c2ecf20Sopenharmony_ci					     &res[0], num_res);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	return PTR_ERR_OR_ZERO(pd);
668c2ecf20Sopenharmony_ci}
678c2ecf20Sopenharmony_cifs_initcall(add_rtc);
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
70