summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8700
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2017-03-15 01:51:54 -0400
committerMichael Sevakis <jethead71@rockbox.org>2017-10-26 14:35:41 -0400
commit1654efc31339972d0e6bd41a499fcffc0a45822e (patch)
tree5fb7f59ab918a3694608bb1138c2c52fb47698c3 /firmware/target/arm/s5l8700
parent7807934a271e9eb7b045cdcd89ba70fb59a91d69 (diff)
downloadrockbox-1654efc31339972d0e6bd41a499fcffc0a45822e.tar.gz
rockbox-1654efc31339972d0e6bd41a499fcffc0a45822e.zip
Unify storage threads into one
* Editing a bunch of drivers' thread routines in order to implement a new feature is tedious. * No matter the number of storage drivers, they share one thread. No extra threads needed for CONFIG_STORAGE_MULTI. * Each has an event callback called by the storage thread. * A default callback is provided to fake sleeping in order to trigger idle callbacks. It could also do other default processing. Changes to it will be part of driver code without editing each one. * Drivers may sleep and wake as they please as long as they give a low pulse on their storage bit to ask to go into sleep mode. Idle callback is called on its behalf and driver immediately put into sleep mode. * Drivers may indicate they are to continue receiving events in USB mode, otherwise they receve nothing until disconnect (they do receive SYS_USB_DISCONNECTED no matter what). * Rework a few things to keep the callback implementation sane and maintainable. ata.c was dreadful with all those bools; make it a state machine and easier to follow. Remove last_user_activity; it has no purpose that isn't served by keeping the disk active through last_disk_activity instead. * Even-out stack sizes partly because of a lack of a decent place to define them by driver or SoC or whatever; it doesn't seem too critical to do that anyway. Many are simply too large while at least one isn't really adequate. They may be individually overridden if necessary (figure out where). The thread uses the greatest size demanded. Newer file code is much more frugal with stack space. I barely see use crack 50% after idle callbacks (usually mid-40s). Card insert/eject doesn't demand much. * No forcing of idle callbacks. If it isn't necessary for one or more non-disk storage types, it really isn't any more necessary for disk storage. Besides, it makes the whole thing easier to implement. Change-Id: Id30c284d82a8af66e47f2cfe104c52cbd8aa7215
Diffstat (limited to 'firmware/target/arm/s5l8700')
-rw-r--r--firmware/target/arm/s5l8700/ata-nand-s5l8700.c1
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c76
2 files changed, 41 insertions, 36 deletions
diff --git a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
index 227f6b703b..7f68b82a0d 100644
--- a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
+++ b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
@@ -52,7 +52,6 @@ void nand_spindown(int seconds)
52 52
53void nand_sleep(void) 53void nand_sleep(void)
54{ 54{
55 nand_power_down();
56} 55}
57 56
58void nand_sleepnow(void) 57void nand_sleepnow(void)
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
index 1698dc2b9b..4b74405c1c 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
@@ -31,8 +31,7 @@
31#include <mmu-arm.h> 31#include <mmu-arm.h>
32#include <string.h> 32#include <string.h>
33#include "led.h" 33#include "led.h"
34#include "ata_idle_notify.h" 34#include "storage.h"
35
36 35
37#define NAND_CMD_READ 0x00 36#define NAND_CMD_READ 0x00
38#define NAND_CMD_PROGCNFRM 0x10 37#define NAND_CMD_PROGCNFRM 0x10
@@ -91,7 +90,6 @@ static int nand_powered = 0;
91static int nand_interleaved = 0; 90static int nand_interleaved = 0;
92static int nand_cached = 0; 91static int nand_cached = 0;
93static long nand_last_activity_value = -1; 92static long nand_last_activity_value = -1;
94static long nand_stack[DEFAULT_STACK_SIZE];
95 93
96static struct mutex nand_mtx; 94static struct mutex nand_mtx;
97static struct semaphore nand_complete; 95static struct semaphore nand_complete;
@@ -359,20 +357,22 @@ void nand_power_up(void)
359 357
360void nand_power_down(void) 358void nand_power_down(void)
361{ 359{
362 if (!nand_powered) return;
363 mutex_lock(&nand_mtx); 360 mutex_lock(&nand_mtx);
364 pmu_ldo_power_off(4); 361 if (nand_powered)
365 PCON2 = 0x11111111; 362 {
366 PDAT2 = 0; 363 pmu_ldo_power_off(4);
367 PCON3 = 0x11111111; 364 PCON2 = 0x11111111;
368 PDAT3 = 0; 365 PDAT2 = 0;
369 PCON4 = 0x11111111; 366 PCON3 = 0x11111111;
370 PDAT4 = 0; 367 PDAT3 = 0;
371 PCON5 = (PCON5 & ~0xF) | 1; 368 PCON4 = 0x11111111;
372 PUNK5 = 1; 369 PDAT4 = 0;
373 PWRCONEXT |= 0x40; 370 PCON5 = (PCON5 & ~0xF) | 1;
374 PWRCON |= 0x100000; 371 PUNK5 = 1;
375 nand_powered = 0; 372 PWRCONEXT |= 0x40;
373 PWRCON |= 0x100000;
374 nand_powered = 0;
375 }
376 mutex_unlock(&nand_mtx); 376 mutex_unlock(&nand_mtx);
377} 377}
378 378
@@ -714,20 +714,6 @@ const struct nand_device_info_type* nand_get_device_type(uint32_t bank)
714 return &nand_deviceinfotable[nand_type[bank]]; 714 return &nand_deviceinfotable[nand_type[bank]];
715} 715}
716 716
717static void nand_thread(void)
718{
719 while (1)
720 {
721 if (TIME_AFTER(current_tick, nand_last_activity_value + HZ / 5)
722 && nand_powered)
723 {
724 call_storage_idle_notifys(false);
725 nand_power_down();
726 }
727 sleep(HZ / 10);
728 }
729}
730
731int nand_device_init(void) 717int nand_device_init(void)
732{ 718{
733 mutex_init(&nand_mtx); 719 mutex_init(&nand_mtx);
@@ -776,10 +762,30 @@ int nand_device_init(void)
776 nand_cached = ((nand_deviceinfotable[nand_type[0]].id >> 23) & 1); 762 nand_cached = ((nand_deviceinfotable[nand_type[0]].id >> 23) & 1);
777 763
778 nand_last_activity_value = current_tick; 764 nand_last_activity_value = current_tick;
779 create_thread(nand_thread, nand_stack,
780 sizeof(nand_stack), 0, "nand"
781 IF_PRIO(, PRIORITY_USER_INTERFACE)
782 IF_COP(, CPU));
783
784 return 0; 765 return 0;
785} 766}
767
768int nand_event(long id, intptr_t data)
769{
770 int rc = 0;
771
772 if (LIKELY(id == Q_STORAGE_TICK))
773 {
774 if (!nand_powered ||
775 TIME_BEFORE(current_tick, nand_last_activity_value + HZ / 5))
776 {
777 STG_EVENT_ASSERT_ACTIVE(STORAGE_NAND);
778 }
779 }
780 else if (id == Q_STORAGE_SLEEPNOW)
781 {
782 nand_power_down();
783 }
784 else
785 {
786 rc = storage_event_default_handler(id, data, nand_last_activity_value,
787 STORAGE_NAND);
788 }
789
790 return rc;
791}