From f0a96580ae84cdfbb09db568f296491c699b6a4b Mon Sep 17 00:00:00 2001 From: Michael Sparmann Date: Fri, 9 Oct 2009 20:36:09 +0000 Subject: [PATCH] Core changes to allow storage drivers to do cleanup on shutdown, and iPod Nano 2G shutdown code rework (FS#10668) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23057 a1c6a512-1295-4272-9138-f99709370657 --- firmware/export/config-ipodnano2g.h | 7 +++++ firmware/export/nand.h | 3 ++ firmware/export/storage.h | 16 ++++++++++ firmware/powermgmt.c | 8 +++++ firmware/storage.c | 29 +++++++++++++++++++ firmware/target/arm/ata-nand-telechips.c | 6 ++++ .../target/arm/s5l8700/ata-nand-s5l8700.c | 14 +++++++-- .../arm/s5l8700/ipodnano2g/lcd-nano2g.c | 13 +++++++-- .../arm/s5l8700/ipodnano2g/pmu-nano2g.c | 2 +- .../arm/s5l8700/ipodnano2g/power-nano2g.c | 7 ----- .../arm/s5l8700/ipodnano2g/rtc-nano2g.c | 1 - .../mips/ingenic_jz47xx/ata-nand-jz4740.c | 7 +++++ 12 files changed, 98 insertions(+), 15 deletions(-) diff --git a/firmware/export/config-ipodnano2g.h b/firmware/export/config-ipodnano2g.h index 9d36a37046..641e88860b 100644 --- a/firmware/export/config-ipodnano2g.h +++ b/firmware/export/config-ipodnano2g.h @@ -39,6 +39,9 @@ /* define this to enable JPEG decoding */ #define HAVE_JPEG +/* define this if the LCD can shut down */ +#define HAVE_LCD_SHUTDOWN + /* define this if you can invert the colours on your LCD */ //#define HAVE_LCD_INVERT @@ -58,6 +61,10 @@ #define CONFIG_NAND NAND_SAMSUNG +/* define this if at least one storage driver + needs to do cleanup on shutdown */ +#define HAVE_STORAGE_FLUSH + /* The NAND flash has 2048-byte sectors, and is our only storage */ #define SECTOR_SIZE 2048 diff --git a/firmware/export/nand.h b/firmware/export/nand.h index 67ebe73ddf..60b986dc2f 100644 --- a/firmware/export/nand.h +++ b/firmware/export/nand.h @@ -37,6 +37,9 @@ int nand_init(void); void nand_close(void); int nand_read_sectors(IF_MD2(int drive,) unsigned long start, int count, void* buf); int nand_write_sectors(IF_MD2(int drive,) unsigned long start, int count, const void* buf); +#ifdef HAVE_STORAGE_FLUSH +int nand_flush(void); +#endif void nand_spin(void); int nand_spinup_time(void); /* ticks */ diff --git a/firmware/export/storage.h b/firmware/export/storage.h index fc49d0ce31..cb4ad7fc3a 100644 --- a/firmware/export/storage.h +++ b/firmware/export/storage.h @@ -69,6 +69,9 @@ struct storage_info #define storage_close() ata_close() #define storage_read_sectors(drive, start, count, buf) ata_read_sectors(IF_MD2(drive,) start, count, buf) #define storage_write_sectors(drive, start, count, buf) ata_write_sectors(IF_MD2(drive,) start, count, buf) + #ifdef HAVE_STORAGE_FLUSH + #define storage_flush() (void)0 + #endif #define storage_last_disk_activity() ata_last_disk_activity() #define storage_spinup_time() ata_spinup_time() #define storage_get_identify() ata_get_identify() @@ -92,6 +95,9 @@ struct storage_info #define storage_init() sd_init() #define storage_read_sectors(drive, start, count, buf) sd_read_sectors(IF_MD2(drive,) start, count, buf) #define storage_write_sectors(drive, start, count, buf) sd_write_sectors(IF_MD2(drive,) start, count, buf) + #ifdef HAVE_STORAGE_FLUSH + #define storage_flush() (void)0 + #endif #define storage_last_disk_activity() sd_last_disk_activity() #define storage_spinup_time() 0 #define storage_get_identify() sd_get_identify() @@ -115,6 +121,9 @@ struct storage_info #define storage_init() mmc_init() #define storage_read_sectors(drive, start, count, buf) mmc_read_sectors(IF_MD2(drive,) start, count, buf) #define storage_write_sectors(drive, start, count, buf) mmc_write_sectors(IF_MD2(drive,) start, count, buf) + #ifdef HAVE_STORAGE_FLUSH + #define storage_flush() (void)0 + #endif #define storage_last_disk_activity() mmc_last_disk_activity() #define storage_spinup_time() 0 #define storage_get_identify() mmc_get_identify() @@ -138,6 +147,9 @@ struct storage_info #define storage_init() nand_init() #define storage_read_sectors(drive, start, count, buf) nand_read_sectors(IF_MD2(drive,) start, count, buf) #define storage_write_sectors(drive, start, count, buf) nand_write_sectors(IF_MD2(drive,) start, count, buf) + #ifdef HAVE_STORAGE_FLUSH + #define storage_flush() nand_flush() + #endif #define storage_last_disk_activity() nand_last_disk_activity() #define storage_spinup_time() 0 #define storage_get_identify() nand_get_identify() @@ -161,6 +173,9 @@ struct storage_info #define storage_init() ramdisk_init() #define storage_read_sectors(drive, start, count, buf) ramdisk_read_sectors(IF_MD2(drive,) start, count, buf) #define storage_write_sectors(drive, start, count, buf) ramdisk_write_sectors(IF_MD2(drive,) start, count, buf) + #ifdef HAVE_STORAGE_FLUSH + #define storage_flush() (void)0 + #endif #define storage_last_disk_activity() ramdisk_last_disk_activity() #define storage_spinup_time() 0 #define storage_get_identify() ramdisk_get_identify() @@ -187,6 +202,7 @@ int storage_soft_reset(void); int storage_init(void); int storage_read_sectors(int drive, unsigned long start, int count, void* buf); int storage_write_sectors(int drive, unsigned long start, int count, const void* buf); +int storage_flush(void); void storage_spin(void); void storage_spindown(int seconds); long storage_last_disk_activity(void); diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 6ec0307ae5..e756bac3c2 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -749,6 +749,14 @@ void shutdown_hw(void) #ifdef HAVE_LCD_BITMAP glyph_cache_save(); #endif + +/* Commit pending writes if needed. Even though we don't do write caching, + things like flash translation layers may need this to commit scattered + pages to there final locations. So far only used for iPod Nano 2G. */ +#ifdef HAVE_STORAGE_FLUSH + storage_flush(); +#endif + if (storage_disk_is_active()) storage_spindown(1); } diff --git a/firmware/storage.c b/firmware/storage.c index cee7d1cc8b..d6700d1148 100644 --- a/firmware/storage.c +++ b/firmware/storage.c @@ -293,6 +293,35 @@ int storage_soft_reset(void) return rc; } +#ifdef HAVE_STORAGE_FLUSH +int storage_flush(void) +{ + int rc=0; + +#if (CONFIG_STORAGE & STORAGE_ATA) + //if ((rc=ata_flush())) return rc; +#endif + +#if (CONFIG_STORAGE & STORAGE_MMC) + //if ((rc=mmc_flush())) return rc; +#endif + +#if (CONFIG_STORAGE & STORAGE_SD) + //if ((rc=sd_flush())) return rc; +#endif + +#if (CONFIG_STORAGE & STORAGE_NAND) + if ((rc=nand_flush())) return rc; +#endif + +#if (CONFIG_STORAGE & STORAGE_RAMDISK) + //if ((rc=ramdisk_flush())) return rc; +#endif + + return rc; +} +#endif + void storage_spin(void) { #if (CONFIG_STORAGE & STORAGE_ATA) diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c index 8fd1bbf521..81dde33938 100644 --- a/firmware/target/arm/ata-nand-telechips.c +++ b/firmware/target/arm/ata-nand-telechips.c @@ -866,6 +866,12 @@ int nand_write_sectors(IF_MD2(int drive,) unsigned long start, int count, return -1; } +#ifdef HAVE_STORAGE_FLUSH +int nand_flush(void) +{ + return 0; +} +#endif #ifdef STORAGE_GET_INFO void nand_get_info(IF_MD2(int drive,) struct storage_info *info) diff --git a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c index b3b1314a50..883c167c78 100644 --- a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c +++ b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c @@ -36,9 +36,6 @@ long last_disk_activity = -1; /** static, private data **/ static bool initialized = false; -static long next_yield = 0; -#define MIN_YIELD_PERIOD 2000 - /* API Functions */ void nand_led(bool onoff) @@ -67,6 +64,10 @@ void nand_sleep(void) { } +void nand_sleepnow(void) +{ +} + void nand_spin(void) { } @@ -86,6 +87,13 @@ long nand_last_disk_activity(void) return 0; } +#ifdef HAVE_STORAGE_FLUSH +int nand_flush(void) +{ + return ftl_sync(); +} +#endif + int nand_init(void) { if (ftl_init()) return 1; diff --git a/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c index 76e35ead30..c430a327a2 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c @@ -25,6 +25,7 @@ #include "lcd.h" #include "system.h" #include "cpu.h" +#include "pmu-target.h" /* The Nano 2G has two different LCD types. What we call "type 0" @@ -124,10 +125,11 @@ void lcd_set_flip(bool yesno) } } - - -void lcd_off(void) +void lcd_shutdown(void) { + pmu_write(0x2b, 0); /* Kill the backlight, instantly. */ + pmu_write(0x29, 0); + if (lcd_type == 0) { s5l_lcd_write_cmd_data(R_DISPLAY_CONTROL_1, 0x232); @@ -151,6 +153,11 @@ void lcd_off(void) } } + +void lcd_off(void) +{ +} + void lcd_on(void) { } diff --git a/firmware/target/arm/s5l8700/ipodnano2g/pmu-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/pmu-nano2g.c index 4dd295c21a..ca2b5f2775 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/pmu-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/pmu-nano2g.c @@ -103,4 +103,4 @@ void pmu_switch_power(int gate, int onoff) if (onoff) newval |= 1 << (2 * (gate - 4)); pmu_write(0x3C, newval); } -} \ No newline at end of file +} diff --git a/firmware/target/arm/s5l8700/ipodnano2g/power-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/power-nano2g.c index 31f23ff9ff..cba1514aad 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/power-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/power-nano2g.c @@ -32,13 +32,6 @@ void power_off(void) { - if (ftl_sync() != 0) panicf("Failed to unmount flash!"); - - pmu_write(0x2b, 0); /* Kill the backlight, instantly. */ - pmu_write(0x29, 0); - - lcd_off(); - pmu_switch_power(0, 0); pmu_switch_power(2, 0); pmu_switch_power(3, 0); diff --git a/firmware/target/arm/s5l8700/ipodnano2g/rtc-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/rtc-nano2g.c index 01d64f1c54..bad9581d8f 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/rtc-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/rtc-nano2g.c @@ -52,7 +52,6 @@ int rtc_read_datetime(struct tm *tm) int rtc_write_datetime(const struct tm *tm) { unsigned int i; - int rc, oldlevel; unsigned char buf[7]; buf[0] = tm->tm_sec; diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c index a51dc5e882..bbfffc3264 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c @@ -685,6 +685,13 @@ int nand_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const return -1; } +#ifdef HAVE_STORAGE_FLUSH +int nand_flush(void) +{ + return 0; +} +#endif + void nand_spindown(int seconds) { /* null */