Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: ds1511: clean up ds1511_nvram_read()/ds1511_nvram_write()

The change removes redundant sysfs binary file boundary checks, since
this task is already done on caller side in fs/sysfs/file.c

The change enables burst mode of access to SRAM for any read()/write()
operations, it is worth to mention that this may influence on
userspace, for instance prior to the change

read(fd, buf, 1);
read(fd, buf + 1, 1);

and

read(fd, buf, 2);

sequences of syscalls over DS1511's sysfs "nvram" fd led to different
DS1511 state changes and/or buf content, if some userspace applications
are written specifically for DS1511 and exploit this strange
"feature", they may be impacted.

Also the change corrects NVRAM size accessible to userspace from 255
bytes to 256 bytes.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

authored by

Vladimir Zapolskiy and committed by
Alexandre Belloni
8ccba142 f4843b19

+5 -37
+5 -37
drivers/rtc/rtc-ds1511.c
··· 64 64 #define DS1511_KIE 0x04 65 65 #define DS1511_WDE 0x02 66 66 #define DS1511_WDS 0x01 67 - #define DS1511_RAM_MAX 0xff 67 + #define DS1511_RAM_MAX 0x100 68 68 69 69 #define RTC_CMD DS1511_CONTROL_B 70 70 #define RTC_CMD1 DS1511_CONTROL_A ··· 159 159 /* 160 160 * set wdog enable and wdog 'steering' bit to issue a reset 161 161 */ 162 - rtc_write(DS1511_WDE | DS1511_WDS, RTC_CMD); 162 + rtc_write(rtc_read(RTC_CMD) | DS1511_WDE | DS1511_WDS, RTC_CMD); 163 163 } 164 164 165 165 void ··· 407 407 { 408 408 ssize_t count; 409 409 410 - /* 411 - * if count is more than one, turn on "burst" mode 412 - * turn it off when you're done 413 - */ 414 - if (size > 1) 415 - rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); 416 - 417 - if (pos > DS1511_RAM_MAX) 418 - pos = DS1511_RAM_MAX; 419 - 420 - if (size + pos > DS1511_RAM_MAX + 1) 421 - size = DS1511_RAM_MAX - pos + 1; 422 - 423 410 rtc_write(pos, DS1511_RAMADDR_LSB); 424 - for (count = 0; size > 0; count++, size--) 411 + for (count = 0; count < size; count++) 425 412 *buf++ = rtc_read(DS1511_RAMDATA); 426 - 427 - if (count > 1) 428 - rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); 429 413 430 414 return count; 431 415 } ··· 421 437 { 422 438 ssize_t count; 423 439 424 - /* 425 - * if count is more than one, turn on "burst" mode 426 - * turn it off when you're done 427 - */ 428 - if (size > 1) 429 - rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); 430 - 431 - if (pos > DS1511_RAM_MAX) 432 - pos = DS1511_RAM_MAX; 433 - 434 - if (size + pos > DS1511_RAM_MAX + 1) 435 - size = DS1511_RAM_MAX - pos + 1; 436 - 437 440 rtc_write(pos, DS1511_RAMADDR_LSB); 438 - for (count = 0; size > 0; count++, size--) 441 + for (count = 0; count < size; count++) 439 442 rtc_write(*buf++, DS1511_RAMDATA); 440 - 441 - if (count > 1) 442 - rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); 443 443 444 444 return count; 445 445 } ··· 458 490 /* 459 491 * turn on the clock and the crystal, etc. 460 492 */ 461 - rtc_write(0, RTC_CMD); 493 + rtc_write(DS1511_BME, RTC_CMD); 462 494 rtc_write(0, RTC_CMD1); 463 495 /* 464 496 * clear the wdog counter