Patchwork x86: i2c rtc instead of cmos rtc

login
register
mail settings
Submitter Ed Swierk
Date Jan. 27, 2009, 1:04 a.m.
Message ID <1233018263.14510.112.camel@localhost.localdomain>
Download mbox | patch
Permalink /patch/20364/
State Changes Requested
Headers show

Comments

Ed Swierk - Jan. 27, 2009, 1:04 a.m.
Allows the user to ignore the cmos real-time clock normally found on x86
boards, and to use an i2c rtc in its place.  This is intended to be used
with with CONFIG_RTC_HCTOSYS=y to set the system clock from the rtc
automatically during boot, and with CONFIG_RTC_SYSTOHC=y to have ntpd
update the rtc (see separate patch).

Passing rtc.cmos=0 on the kernel command line ignores the cmos rtc, and
passing a parameter like rtc.i2c=ds1339,1,0x68 enables the i2c rtc named
ds1339 on i2c bus 1, device address 0x68.  The appropriate driver must
be compiled into the kernel to be available when the initcall is
triggered (device_initcall_sync to ensure the i2c device has already
been added).

Signed-off-by: Ed Swierk <eswierk@aristanetworks.com>

---



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
-~----------~----~----~----~------~----~------~--~---
Alessandro Zummo - Jan. 27, 2009, 11:21 a.m.
On Mon, 26 Jan 2009 17:04:23 -0800
Ed Swierk <eswierk@aristanetworks.com> wrote:

> Allows the user to ignore the cmos real-time clock normally found on x86
> boards, and to use an i2c rtc in its place.  This is intended to be used
> with with CONFIG_RTC_HCTOSYS=y to set the system clock from the rtc
> automatically during boot, and with CONFIG_RTC_SYSTOHC=y to have ntpd
> update the rtc (see separate patch).

 can't you just avoid compiling rtc cmos? or compile it as a module and
 load the i2c rtc first?
Ed Swierk - Jan. 29, 2009, 7:21 p.m.
On Tue, Jan 27, 2009 at 3:21 AM, Alessandro Zummo
<alessandro.zummo@towertech.it> wrote:
>  can't you just avoid compiling rtc cmos? or compile it as a module and
>  load the i2c rtc first?

In our embedded application it's more convenient to build all the
drivers needed to support various hardware configurations into the
kernel, and avoid messing with modules. This works fine for devices
that can be detected dynamically, but RTC chips are among the few that
need to be configured statically; my change just relaxes the current
assumption that all x86 boards have a usable CMOS RTC.

--Ed

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
-~----------~----~----~----~------~----~------~--~---
Alessandro Zummo - Jan. 29, 2009, 7:41 p.m.
On Thu, 29 Jan 2009 11:21:58 -0800
Ed Swierk <eswierk@aristanetworks.com> wrote:

> In our embedded application it's more convenient to build all the
> drivers needed to support various hardware configurations into the
> kernel, and avoid messing with modules. This works fine for devices
> that can be detected dynamically, but RTC chips are among the few that
> need to be configured statically; my change just relaxes the current
> assumption that all x86 boards have a usable CMOS RTC.

 While I can't judge on what's convenient to you, I do not feel
 fine in having a kernel option to disable the rtc and another to load
 a specific i2c one.

 However, if there's a strong consensus from other people
 on the matter, I will close an eye and pretend I haven't seen
 the patch slipping thru :)
Ed Swierk - Jan. 29, 2009, 8:05 p.m.
On Thu, Jan 29, 2009 at 11:41 AM, Alessandro Zummo
<alessandro.zummo@towertech.it> wrote:
>  While I can't judge on what's convenient to you, I do not feel
>  fine in having a kernel option to disable the rtc and another to load
>  a specific i2c one.

Would you prefer a single option to select the rtc (something like
rtc.device={cmos|i2c,ds1339,1,0x68})? Or do you object to any option
at all?

--Ed

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
-~----------~----~----~----~------~----~------~--~---
Alessandro Zummo - Jan. 29, 2009, 8:11 p.m.
On Thu, 29 Jan 2009 12:05:26 -0800
Ed Swierk <eswierk@aristanetworks.com> wrote:

> Would you prefer a single option to select the rtc (something like
> rtc.device={cmos|i2c,ds1339,1,0x68})? Or do you object to any option
> at all?

 I object to options of this kind. It took us a lot of efforts to move
 to the new i2c model and to the concept that devices have to be declared
 in the board support code. This kind of hack is in the opposite direction.
Ed Swierk - Jan. 29, 2009, 9:12 p.m.
On Thu, Jan 29, 2009 at 12:11 PM, Alessandro Zummo
<alessandro.zummo@towertech.it> wrote:
>  I object to options of this kind. It took us a lot of efforts to move
>  to the new i2c model and to the concept that devices have to be declared
>  in the board support code. This kind of hack is in the opposite direction.

I see. I encountered board support code when I worked with PowerPC
boards on Linux years ago but I haven't seen this in the x86 arch
code. Can you point me to an example?

--Ed

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
-~----------~----~----~----~------~----~------~--~---
Alessandro Zummo - Jan. 29, 2009, 9:19 p.m.
On Thu, 29 Jan 2009 13:12:49 -0800
Ed Swierk <eswierk@aristanetworks.com> wrote:

> >  I object to options of this kind. It took us a lot of efforts to move
> >  to the new i2c model and to the concept that devices have to be declared
> >  in the board support code. This kind of hack is in the opposite direction.  
> 
> I see. I encountered board support code when I worked with PowerPC
> boards on Linux years ago but I haven't seen this in the x86 arch
> code. Can you point me to an example?

 Under x86 the thing is not well defined, but you can check 

 arch/x86/kernel/olpc.c

 for an example.

 If you just have to load different modules I'd use an initrd
 where you can place all the necessary logic to detect your board

Patch

Index: linux-2.6.28.2/arch/x86/kernel/rtc.c
===================================================================
--- linux-2.6.28.2.orig/arch/x86/kernel/rtc.c
+++ linux-2.6.28.2/arch/x86/kernel/rtc.c
@@ -220,6 +220,9 @@  static struct platform_device rtc_device
 	.num_resources	= ARRAY_SIZE(rtc_resources),
 };
 
+static int cmos = 1;
+module_param(cmos, bool, 0);
+
 static __init int add_rtc_cmos(void)
 {
 #ifdef CONFIG_PNP
@@ -228,7 +231,11 @@  static __init int add_rtc_cmos(void)
 	struct pnp_dev *dev;
 	struct pnp_id *id;
 	int i;
+#endif
 
+	if (!cmos)
+		return 0;
+#ifdef CONFIG_PNP
 	pnp_for_each_dev(dev) {
 		for (id = dev->id; id; id = id->next) {
 			for (i = 0; i < ARRAY_SIZE(ids); i++) {
@@ -245,3 +252,41 @@  static __init int add_rtc_cmos(void)
 	return 0;
 }
 device_initcall(add_rtc_cmos);
+
+#include <linux/i2c.h>
+
+static char *i2c[3] = { NULL, NULL, NULL };
+module_param_array(i2c, charp, NULL, 0);
+
+static int setup_rtc_i2c(void)
+{
+	struct i2c_adapter *adapter;
+	struct i2c_board_info info = {};
+	int adapter_id;
+	unsigned short addrs[] = { 0, I2C_CLIENT_END };
+	struct i2c_client *c;
+	unsigned long num;
+
+	if (!i2c[0] || !i2c[1] || !i2c[2])
+		return 0;
+
+	strlcpy(info.type, i2c[0], I2C_NAME_SIZE);
+	if (strict_strtoul(i2c[1], 0, &num))
+		return 0;
+	adapter_id = num;
+	if (strict_strtoul(i2c[2], 0, &num))
+		return 0;
+	addrs[0] = num;
+
+	adapter = i2c_get_adapter(adapter_id);
+	if (!adapter)
+		return 0;
+
+	c = i2c_new_probed_device(adapter, &info, addrs);
+	if (c && c->driver == NULL) {
+		i2c_unregister_device(c);
+	}
+	i2c_put_adapter(adapter);
+	return 0;
+}
+device_initcall_sync(setup_rtc_i2c);