From 0abc920116303e81702a38429a1b61a896e02b37 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 23 Mar 2012 15:02:31 -0700 Subject: rtc: convert rtc i2c drivers to module_i2c_driver Factor out some boilerplate code for i2c driver registration into module_i2c_driver. Signed-off-by: Axel Lin Cc: Piotr Ziecik Cc: Alessandro Zummo Cc: Scott Wood Cc: Srikanth Srinivasan Cc: Mike Rapoport Cc: Sergey Lapin Cc: Roman Fietze Cc: Herbert Valerio Riedel Cc: Alexander Bigga Cc: Dale Farnsworth Cc: Gregory Hermant Cc: Wolfgang Grandegger Cc: Martyn Welch Cc: Byron Bradley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers/rtc/rtc-ds1307.c') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 62b0763b7b9..58edcb07674 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -938,17 +938,7 @@ static struct i2c_driver ds1307_driver = { .id_table = ds1307_id, }; -static int __init ds1307_init(void) -{ - return i2c_add_driver(&ds1307_driver); -} -module_init(ds1307_init); - -static void __exit ds1307_exit(void) -{ - i2c_del_driver(&ds1307_driver); -} -module_exit(ds1307_exit); +module_i2c_driver(ds1307_driver); MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 32d322bcb0d6886084197247e30aa130956d5978 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 23 Mar 2012 15:02:36 -0700 Subject: rtc: ds1307: refactor chip_desc table The chip_desc table is suboptimal. Currently it requires an entry for every new chip type, even if it is empty. This has already been forgotten for the ds1388. Refactor the code, so new entries are only needed, when they chip type really needs a (non-empty) description. Also make the table visually more appealing. Signed-off-by: Wolfram Sang Cc: Austin Boyle Cc: David Anders Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 48 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) (limited to 'drivers/rtc/rtc-ds1307.c') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 58edcb07674..5098e1ad3a3 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -36,6 +36,7 @@ enum ds_type { m41t00, mcp7941x, rx_8025, + last_ds_type /* always last */ // rs5c372 too? different address... }; @@ -120,30 +121,23 @@ struct chip_desc { unsigned alarm:1; }; -static const struct chip_desc chips[] = { -[ds_1307] = { - .nvram56 = 1, -}, -[ds_1337] = { - .alarm = 1, -}, -[ds_1338] = { - .nvram56 = 1, -}, -[ds_1339] = { - .alarm = 1, -}, -[ds_1340] = { -}, -[ds_3231] = { - .alarm = 1, -}, -[m41t00] = { -}, -[mcp7941x] = { -}, -[rx_8025] = { -}, }; +static const struct chip_desc chips[last_ds_type] = { + [ds_1307] = { + .nvram56 = 1, + }, + [ds_1337] = { + .alarm = 1, + }, + [ds_1338] = { + .nvram56 = 1, + }, + [ds_1339] = { + .alarm = 1, + }, + [ds_3231] = { + .alarm = 1, + }, +}; static const struct i2c_device_id ds1307_id[] = { { "ds1307", ds_1307 }, @@ -836,11 +830,7 @@ read_rtc: } break; - case rx_8025: - case ds_1337: - case ds_1339: - case ds_1388: - case ds_3231: + default: break; } -- cgit v1.2.3-70-g09d2 From b24a7267709bb0adb694364572478f919e9c7390 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 23 Mar 2012 15:02:37 -0700 Subject: rtc: ds1307: simplify irq setup code No need to have two seperate if-blocks for setting up the irq. Signed-off-by: Wolfram Sang Tested-by: David Anders Cc: Austin Boyle Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/rtc/rtc-ds1307.c') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 5098e1ad3a3..d4543e8730c 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -646,11 +646,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, case ds_1337: case ds_1339: case ds_3231: - /* has IRQ? */ - if (ds1307->client->irq > 0 && chip->alarm) { - INIT_WORK(&ds1307->work, ds1307_work); - want_irq = true; - } /* get registers that the "rtc" read below won't read... */ tmp = ds1307->read_block_data(ds1307->client, DS1337_REG_CONTROL, 2, buf); @@ -668,10 +663,14 @@ static int __devinit ds1307_probe(struct i2c_client *client, * For some variants, be sure alarms can trigger when we're * running on Vbackup (BBSQI/BBSQW) */ - if (want_irq) { + if (ds1307->client->irq > 0 && chip->alarm) { + INIT_WORK(&ds1307->work, ds1307_work); + ds1307->regs[0] |= DS1337_BIT_INTCN | bbsqi_bitpos[ds1307->type]; ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); + + want_irq = true; } i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, -- cgit v1.2.3-70-g09d2 From 40ce972d59fcfd4979e5de04456122447b40c1cf Mon Sep 17 00:00:00 2001 From: David Anders Date: Fri, 23 Mar 2012 15:02:37 -0700 Subject: rtc: ds1307: comment and format cleanup Do some cleanup of the comment sections as well as correct some formatting issues reported by checkpatch.pl. Signed-off-by: David Anders Signed-off-by: Wolfram Sang Cc: Austin Boyle Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'drivers/rtc/rtc-ds1307.c') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index d4543e8730c..84ab971978c 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -20,7 +20,8 @@ -/* We can't determine type by probing, but if we expect pre-Linux code +/* + * We can't determine type by probing, but if we expect pre-Linux code * to have set the chip up as a clock (turning on the oscillator and * setting the date and time), Linux can ignore the non-clock features. * That's a natural job for a factory or repair bench. @@ -37,7 +38,7 @@ enum ds_type { mcp7941x, rx_8025, last_ds_type /* always last */ - // rs5c372 too? different address... + /* rs5c372 too? different address... */ }; @@ -59,7 +60,8 @@ enum ds_type { # define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */ #define DS1307_REG_YEAR 0x06 /* 00-99 */ -/* Other registers (control, status, alarms, trickle charge, NVRAM, etc) +/* + * Other registers (control, status, alarms, trickle charge, NVRAM, etc) * start at 7, and they differ a LOT. Only control and status matter for * basic RTC date and time functionality; be careful using them. */ @@ -366,6 +368,11 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | DS1340_BIT_CENTURY; break; case mcp7941x: + /* + * these bits were cleared when preparing the date/time + * values and need to be set again before writing the + * buffer out to the device. + */ buf[DS1307_REG_SECS] |= MCP7941X_BIT_ST; buf[DS1307_REG_WDAY] |= MCP7941X_BIT_VBATEN; break; @@ -411,7 +418,8 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) ds1307->regs[6], ds1307->regs[7], ds1307->regs[8]); - /* report alarm time (ALARM1); assume 24 hour and day-of-month modes, + /* + * report alarm time (ALARM1); assume 24 hour and day-of-month modes, * and that all four fields are checked matches */ t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f); @@ -439,7 +447,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) { - struct i2c_client *client = to_i2c_client(dev); + struct i2c_client *client = to_i2c_client(dev); struct ds1307 *ds1307 = i2c_get_clientdata(client); unsigned char *buf = ds1307->regs; u8 control, status; @@ -602,8 +610,6 @@ static struct bin_attribute nvram = { /*----------------------------------------------------------------------*/ -static struct i2c_driver ds1307_driver; - static int __devinit ds1307_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -624,7 +630,8 @@ static int __devinit ds1307_probe(struct i2c_client *client, && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return -EIO; - if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) + ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL); + if (!ds1307) return -ENOMEM; i2c_set_clientdata(client, ds1307); @@ -659,7 +666,8 @@ static int __devinit ds1307_probe(struct i2c_client *client, if (ds1307->regs[0] & DS1337_BIT_nEOSC) ds1307->regs[0] &= ~DS1337_BIT_nEOSC; - /* Using IRQ? Disable the square wave and both alarms. + /* + * Using IRQ? Disable the square wave and both alarms. * For some variants, be sure alarms can trigger when we're * running on Vbackup (BBSQI/BBSQW) */ @@ -765,7 +773,8 @@ read_rtc: goto exit_free; } - /* minimal sanity checking; some chips (like DS1340) don't + /* + * minimal sanity checking; some chips (like DS1340) don't * specify the extra bits as must-be-zero, but there are * still a few values that are clearly out-of-range. */ @@ -837,7 +846,8 @@ read_rtc: switch (ds1307->type) { case ds_1340: case m41t00: - /* NOTE: ignores century bits; fix before deploying + /* + * NOTE: ignores century bits; fix before deploying * systems that will run through year 2100. */ break; @@ -847,7 +857,8 @@ read_rtc: if (!(tmp & DS1307_BIT_12HR)) break; - /* Be sure we're in 24 hour mode. Multi-master systems + /* + * Be sure we're in 24 hour mode. Multi-master systems * take note... */ tmp = bcd2bin(tmp & 0x1f); @@ -902,7 +913,7 @@ exit_free: static int __devexit ds1307_remove(struct i2c_client *client) { - struct ds1307 *ds1307 = i2c_get_clientdata(client); + struct ds1307 *ds1307 = i2c_get_clientdata(client); if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) { free_irq(client->irq, client); -- cgit v1.2.3-70-g09d2 From 9eab0a788d2d6e513f43b7c0e5bb9d60446233cb Mon Sep 17 00:00:00 2001 From: Austin Boyle Date: Fri, 23 Mar 2012 15:02:38 -0700 Subject: rtc: ds1307: generalise ram size and offset Generalise NVRAM to support RAM with other size and offset, such as the 64 bytes of SRAM on the mcp7941x. [rdunlap@xenotime.net: fix printk format warning] Signed-off-by: Austin Boyle Signed-off-by: Wolfram Sang Signed-off-by: Randy Dunlap Cc: David Anders Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 78 +++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 31 deletions(-) (limited to 'drivers/rtc/rtc-ds1307.c') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 84ab971978c..cd188ab72f7 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -105,6 +105,8 @@ enum ds_type { struct ds1307 { u8 offset; /* register's offset */ u8 regs[11]; + u16 nvram_offset; + struct bin_attribute *nvram; enum ds_type type; unsigned long flags; #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ @@ -119,19 +121,22 @@ struct ds1307 { }; struct chip_desc { - unsigned nvram56:1; unsigned alarm:1; + u16 nvram_offset; + u16 nvram_size; }; static const struct chip_desc chips[last_ds_type] = { [ds_1307] = { - .nvram56 = 1, + .nvram_offset = 8, + .nvram_size = 56, }, [ds_1337] = { .alarm = 1, }, [ds_1338] = { - .nvram56 = 1, + .nvram_offset = 8, + .nvram_size = 56, }, [ds_1339] = { .alarm = 1, @@ -139,6 +144,11 @@ static const struct chip_desc chips[last_ds_type] = { [ds_3231] = { .alarm = 1, }, + [mcp7941x] = { + /* this is battery backed SRAM */ + .nvram_offset = 0x20, + .nvram_size = 0x40, + }, }; static const struct i2c_device_id ds1307_id[] = { @@ -543,8 +553,6 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { /*----------------------------------------------------------------------*/ -#define NVRAM_SIZE 56 - static ssize_t ds1307_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, @@ -557,14 +565,15 @@ ds1307_nvram_read(struct file *filp, struct kobject *kobj, client = kobj_to_i2c_client(kobj); ds1307 = i2c_get_clientdata(client); - if (unlikely(off >= NVRAM_SIZE)) + if (unlikely(off >= ds1307->nvram->size)) return 0; - if ((off + count) > NVRAM_SIZE) - count = NVRAM_SIZE - off; + if ((off + count) > ds1307->nvram->size) + count = ds1307->nvram->size - off; if (unlikely(!count)) return count; - result = ds1307->read_block_data(client, 8 + off, count, buf); + result = ds1307->read_block_data(client, ds1307->nvram_offset + off, + count, buf); if (result < 0) dev_err(&client->dev, "%s error %d\n", "nvram read", result); return result; @@ -582,14 +591,15 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, client = kobj_to_i2c_client(kobj); ds1307 = i2c_get_clientdata(client); - if (unlikely(off >= NVRAM_SIZE)) + if (unlikely(off >= ds1307->nvram->size)) return -EFBIG; - if ((off + count) > NVRAM_SIZE) - count = NVRAM_SIZE - off; + if ((off + count) > ds1307->nvram->size) + count = ds1307->nvram->size - off; if (unlikely(!count)) return count; - result = ds1307->write_block_data(client, 8 + off, count, buf); + result = ds1307->write_block_data(client, ds1307->nvram_offset + off, + count, buf); if (result < 0) { dev_err(&client->dev, "%s error %d\n", "nvram write", result); return result; @@ -597,17 +607,6 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, return count; } -static struct bin_attribute nvram = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUSR, - }, - - .read = ds1307_nvram_read, - .write = ds1307_nvram_write, - .size = NVRAM_SIZE, -}; - /*----------------------------------------------------------------------*/ static int __devinit ds1307_probe(struct i2c_client *client, @@ -894,16 +893,31 @@ read_rtc: dev_dbg(&client->dev, "got IRQ %d\n", client->irq); } - if (chip->nvram56) { - err = sysfs_create_bin_file(&client->dev.kobj, &nvram); - if (err == 0) { - set_bit(HAS_NVRAM, &ds1307->flags); - dev_info(&client->dev, "56 bytes nvram\n"); + if (chip->nvram_size) { + ds1307->nvram = kzalloc(sizeof(struct bin_attribute), + GFP_KERNEL); + if (!ds1307->nvram) { + err = -ENOMEM; + goto exit_nvram; + } + ds1307->nvram->attr.name = "nvram"; + ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; + ds1307->nvram->read = ds1307_nvram_read, + ds1307->nvram->write = ds1307_nvram_write, + ds1307->nvram->size = chip->nvram_size; + ds1307->nvram_offset = chip->nvram_offset; + err = sysfs_create_bin_file(&client->dev.kobj, ds1307->nvram); + if (err) { + kfree(ds1307->nvram); + goto exit_nvram; } + set_bit(HAS_NVRAM, &ds1307->flags); + dev_info(&client->dev, "%zu bytes nvram\n", ds1307->nvram->size); } return 0; +exit_nvram: exit_irq: rtc_device_unregister(ds1307->rtc); exit_free: @@ -920,8 +934,10 @@ static int __devexit ds1307_remove(struct i2c_client *client) cancel_work_sync(&ds1307->work); } - if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) - sysfs_remove_bin_file(&client->dev.kobj, &nvram); + if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) { + sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram); + kfree(ds1307->nvram); + } rtc_device_unregister(ds1307->rtc); kfree(ds1307); -- cgit v1.2.3-70-g09d2