summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-04-25 14:17:45 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-04-25 14:27:35 +0000
commit77188e41f5c9966432a0fbb3bffd2069d53cc608 (patch)
tree4a98a7739dcfdc8b9aaa9335602533d4be32c502
parenta2dfafb2b266ad5841306e96adb3abfbe9ae87a6 (diff)
downloadrockbox-77188e41f5c9966432a0fbb3bffd2069d53cc608.tar.gz
rockbox-77188e41f5c9966432a0fbb3bffd2069d53cc608.zip
X1000: remove bogus GPIO Z mutex
There's absolutely no way for gpio_config() to get called from two different threads due to the co-operative threading model, and it is unsafe to call from IRQ context no matter what we do. Change-Id: I58f7d1f68c7a414610bb020e26b774cb1015a3b0
-rw-r--r--firmware/target/mips/ingenic_x1000/gpio-x1000.c24
-rw-r--r--firmware/target/mips/ingenic_x1000/gpio-x1000.h11
2 files changed, 4 insertions, 31 deletions
diff --git a/firmware/target/mips/ingenic_x1000/gpio-x1000.c b/firmware/target/mips/ingenic_x1000/gpio-x1000.c
index 8e93f865bf..40e4c5e631 100644
--- a/firmware/target/mips/ingenic_x1000/gpio-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/gpio-x1000.c
@@ -22,16 +22,8 @@
22#include "gpio-x1000.h" 22#include "gpio-x1000.h"
23#include "kernel.h" 23#include "kernel.h"
24 24
25#ifndef BOOTLOADER_SPL
26struct mutex gpio_z_mutex;
27#endif
28
29void gpio_init(void) 25void gpio_init(void)
30{ 26{
31#ifndef BOOTLOADER_SPL
32 mutex_init(&gpio_z_mutex);
33#endif
34
35 /* Any GPIO pins left in an IRQ trigger state need to be switched off, 27 /* Any GPIO pins left in an IRQ trigger state need to be switched off,
36 * because the drivers won't be ready to handle the interrupts until they 28 * because the drivers won't be ready to handle the interrupts until they
37 * get initialized later in the boot. */ 29 * get initialized later in the boot. */
@@ -44,20 +36,6 @@ void gpio_init(void)
44 } 36 }
45} 37}
46 38
47void gpio_lock(void)
48{
49#ifndef BOOTLOADER_SPL
50 mutex_lock(&gpio_z_mutex);
51#endif
52}
53
54void gpio_unlock(void)
55{
56#ifndef BOOTLOADER_SPL
57 mutex_unlock(&gpio_z_mutex);
58#endif
59}
60
61void gpio_config(int port, unsigned pinmask, int func) 39void gpio_config(int port, unsigned pinmask, int func)
62{ 40{
63 unsigned intr = REG_GPIO_INT(port); 41 unsigned intr = REG_GPIO_INT(port);
@@ -65,7 +43,6 @@ void gpio_config(int port, unsigned pinmask, int func)
65 unsigned pat1 = REG_GPIO_PAT1(port); 43 unsigned pat1 = REG_GPIO_PAT1(port);
66 unsigned pat0 = REG_GPIO_PAT0(port); 44 unsigned pat0 = REG_GPIO_PAT0(port);
67 45
68 gpio_lock();
69 if(func & 8) jz_set(GPIO_INT(GPIO_Z), (intr & pinmask) ^ pinmask); 46 if(func & 8) jz_set(GPIO_INT(GPIO_Z), (intr & pinmask) ^ pinmask);
70 else jz_clr(GPIO_INT(GPIO_Z), (~intr & pinmask) ^ pinmask); 47 else jz_clr(GPIO_INT(GPIO_Z), (~intr & pinmask) ^ pinmask);
71 if(func & 4) jz_set(GPIO_MSK(GPIO_Z), (mask & pinmask) ^ pinmask); 48 if(func & 4) jz_set(GPIO_MSK(GPIO_Z), (mask & pinmask) ^ pinmask);
@@ -75,6 +52,5 @@ void gpio_config(int port, unsigned pinmask, int func)
75 if(func & 1) jz_set(GPIO_PAT0(GPIO_Z), (pat0 & pinmask) ^ pinmask); 52 if(func & 1) jz_set(GPIO_PAT0(GPIO_Z), (pat0 & pinmask) ^ pinmask);
76 else jz_clr(GPIO_PAT0(GPIO_Z), (~pat0 & pinmask) ^ pinmask); 53 else jz_clr(GPIO_PAT0(GPIO_Z), (~pat0 & pinmask) ^ pinmask);
77 REG_GPIO_Z_GID2LD = port; 54 REG_GPIO_Z_GID2LD = port;
78 gpio_unlock();
79 gpio_set_pull(port, pinmask, func & 16); 55 gpio_set_pull(port, pinmask, func & 16);
80} 56}
diff --git a/firmware/target/mips/ingenic_x1000/gpio-x1000.h b/firmware/target/mips/ingenic_x1000/gpio-x1000.h
index f1a65b37b5..cfbe86338a 100644
--- a/firmware/target/mips/ingenic_x1000/gpio-x1000.h
+++ b/firmware/target/mips/ingenic_x1000/gpio-x1000.h
@@ -26,12 +26,11 @@
26 * -------- 26 * --------
27 * 27 *
28 * To assign a new function to a GPIO, call gpio_config(). This uses the 28 * To assign a new function to a GPIO, call gpio_config(). This uses the
29 * hardware's GPIO Z facility to atomically most GPIO registers at once, 29 * hardware's GPIO Z facility to atomically set most GPIO registers at once,
30 * so it can be used to make any state transition safely. Since GPIO Z is 30 * so it can be used to make any state transition safely. Since GPIO Z is
31 * protected by a mutex, you can't call gpio_config() from interrupt context. 31 * a global hardware resource, it is unsafe to call gpio_config() from IRQ
32 * 32 * context -- if the interrupted code was also running gpio_config(), then
33 * If you need to use GPIO Z directly, then use gpio_lock() and gpio_unlock() 33 * the results would be unpredictable.
34 * to acquire the mutex.
35 * 34 *
36 * Depending on the current GPIO state, certain state transitions are safe to 35 * Depending on the current GPIO state, certain state transitions are safe to
37 * perform without locking, as they only change one register: 36 * perform without locking, as they only change one register:
@@ -74,8 +73,6 @@
74#define GPIO_IRQ_EDGE(i) (0x1e|((i)&1)) 73#define GPIO_IRQ_EDGE(i) (0x1e|((i)&1))
75 74
76extern void gpio_init(void); 75extern void gpio_init(void);
77extern void gpio_lock(void);
78extern void gpio_unlock(void);
79extern void gpio_config(int port, unsigned pinmask, int func); 76extern void gpio_config(int port, unsigned pinmask, int func);
80 77
81static inline void gpio_out_level(int port, unsigned pinmask, int level) 78static inline void gpio_out_level(int port, unsigned pinmask, int level)