Commit e2d8a714a7e6047124581b93d1cfe9c7702cedd4

Authored by Simon Glass
Committed by Tom Rini
1 parent 96495d90fe

sandbox: Convert GPIOs to use driver model

Convert sandbox over to use driver model GPIOs.

Signed-off-by: Simon Glass <sjg@chromium.org>

Showing 4 changed files with 151 additions and 88 deletions Side-by-side Diff

arch/sandbox/include/asm/gpio.h
... ... @@ -29,7 +29,7 @@
29 29 * @param gp GPIO number
30 30 * @return -1 on error, 0 if GPIO is low, >0 if high
31 31 */
32   -int sandbox_gpio_get_value(unsigned gp);
  32 +int sandbox_gpio_get_value(struct device *dev, unsigned int offset);
33 33  
34 34 /**
35 35 * Set the simulated value of a GPIO (used only in sandbox test code)
... ... @@ -38,7 +38,7 @@
38 38 * @param value value to set (0 for low, non-zero for high)
39 39 * @return -1 on error, 0 if ok
40 40 */
41   -int sandbox_gpio_set_value(unsigned gp, int value);
  41 +int sandbox_gpio_set_value(struct device *dev, unsigned int offset, int value);
42 42  
43 43 /**
44 44 * Return the simulated direction of a GPIO (used only in sandbox test code)
... ... @@ -46,7 +46,7 @@
46 46 * @param gp GPIO number
47 47 * @return -1 on error, 0 if GPIO is input, >0 if output
48 48 */
49   -int sandbox_gpio_get_direction(unsigned gp);
  49 +int sandbox_gpio_get_direction(struct device *dev, unsigned int offset);
50 50  
51 51 /**
52 52 * Set the simulated direction of a GPIO (used only in sandbox test code)
... ... @@ -55,12 +55,8 @@
55 55 * @param output 0 to set as input, 1 to set as output
56 56 * @return -1 on error, 0 if ok
57 57 */
58   -int sandbox_gpio_set_direction(unsigned gp, int output);
59   -
60   -/* Display information about each GPIO */
61   -void gpio_info(void);
62   -
63   -#define gpio_status() gpio_info()
  58 +int sandbox_gpio_set_direction(struct device *dev, unsigned int offset,
  59 + int output);
64 60  
65 61 #endif
board/sandbox/sandbox/sandbox.c
... ... @@ -4,7 +4,7 @@
4 4 */
5 5  
6 6 #include <common.h>
7   -
  7 +#include <dm.h>
8 8 #include <os.h>
9 9  
10 10 /*
... ... @@ -13,6 +13,11 @@
13 13 * Here we initialize it.
14 14 */
15 15 gd_t *gd;
  16 +
  17 +/* Add a simple GPIO device */
  18 +U_BOOT_DEVICE(gpio_sandbox) = {
  19 + .name = "gpio_sandbox",
  20 +};
16 21  
17 22 void flush_cache(unsigned long start, unsigned long size)
18 23 {
drivers/gpio/sandbox.c
... ... @@ -4,8 +4,13 @@
4 4 */
5 5  
6 6 #include <common.h>
  7 +#include <dm.h>
  8 +#include <fdtdec.h>
  9 +#include <malloc.h>
7 10 #include <asm/gpio.h>
8 11  
  12 +DECLARE_GLOBAL_DATA_PTR;
  13 +
9 14 /* Flags for each GPIO */
10 15 #define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */
11 16 #define GPIOF_HIGH (1 << 1) /* Currently set high */
12 17  
13 18  
14 19  
15 20  
16 21  
17 22  
18 23  
19 24  
... ... @@ -16,34 +21,30 @@
16 21 u8 flags; /* flags (GPIOF_...) */
17 22 };
18 23  
19   -/*
20   - * State of GPIOs
21   - * TODO: Put this into sandbox state
22   - */
23   -static struct gpio_state state[CONFIG_SANDBOX_GPIO_COUNT];
24   -
25 24 /* Access routines for GPIO state */
26   -static u8 *get_gpio_flags(unsigned gp)
  25 +static u8 *get_gpio_flags(struct device *dev, unsigned offset)
27 26 {
28   - /* assert()'s could be disabled, so make sure we handle that */
29   - assert(gp < ARRAY_SIZE(state));
30   - if (gp >= ARRAY_SIZE(state)) {
  27 + struct gpio_dev_priv *uc_priv = dev->uclass_priv;
  28 + struct gpio_state *state = dev_get_priv(dev);
  29 +
  30 + if (offset >= uc_priv->gpio_count) {
31 31 static u8 invalid_flags;
32   - printf("sandbox_gpio: error: invalid gpio %u\n", gp);
  32 + printf("sandbox_gpio: error: invalid gpio %u\n", offset);
33 33 return &invalid_flags;
34 34 }
35 35  
36   - return &state[gp].flags;
  36 + return &state[offset].flags;
37 37 }
38 38  
39   -static int get_gpio_flag(unsigned gp, int flag)
  39 +static int get_gpio_flag(struct device *dev, unsigned offset, int flag)
40 40 {
41   - return (*get_gpio_flags(gp) & flag) != 0;
  41 + return (*get_gpio_flags(dev, offset) & flag) != 0;
42 42 }
43 43  
44   -static int set_gpio_flag(unsigned gp, int flag, int value)
  44 +static int set_gpio_flag(struct device *dev, unsigned offset, int flag,
  45 + int value)
45 46 {
46   - u8 *gpio = get_gpio_flags(gp);
  47 + u8 *gpio = get_gpio_flags(dev, offset);
47 48  
48 49 if (value)
49 50 *gpio |= flag;
50 51  
... ... @@ -53,11 +54,12 @@
53 54 return 0;
54 55 }
55 56  
56   -static int check_reserved(unsigned gpio, const char *func)
  57 +static int check_reserved(struct device *dev, unsigned offset,
  58 + const char *func)
57 59 {
58   - if (!get_gpio_flag(gpio, GPIOF_RESERVED)) {
59   - printf("sandbox_gpio: %s: error: gpio %u not reserved\n",
60   - func, gpio);
  60 + if (!get_gpio_flag(dev, offset, GPIOF_RESERVED)) {
  61 + printf("sandbox_gpio: %s: error: offset %u not reserved\n",
  62 + func, offset);
61 63 return -1;
62 64 }
63 65  
64 66  
65 67  
66 68  
67 69  
68 70  
69 71  
70 72  
71 73  
72 74  
73 75  
74 76  
75 77  
76 78  
77 79  
78 80  
79 81  
80 82  
81 83  
82 84  
83 85  
84 86  
85 87  
86 88  
87 89  
88 90  
89 91  
90 92  
91 93  
92 94  
93 95  
94 96  
95 97  
96 98  
97 99  
98 100  
99 101  
100 102  
101 103  
102 104  
103 105  
... ... @@ -68,127 +70,186 @@
68 70 * Back-channel sandbox-internal-only access to GPIO state
69 71 */
70 72  
71   -int sandbox_gpio_get_value(unsigned gp)
  73 +int sandbox_gpio_get_value(struct device *dev, unsigned offset)
72 74 {
73   - if (get_gpio_flag(gp, GPIOF_OUTPUT))
74   - debug("sandbox_gpio: get_value on output gpio %u\n", gp);
75   - return get_gpio_flag(gp, GPIOF_HIGH);
  75 + if (get_gpio_flag(dev, offset, GPIOF_OUTPUT))
  76 + debug("sandbox_gpio: get_value on output gpio %u\n", offset);
  77 + return get_gpio_flag(dev, offset, GPIOF_HIGH);
76 78 }
77 79  
78   -int sandbox_gpio_set_value(unsigned gp, int value)
  80 +int sandbox_gpio_set_value(struct device *dev, unsigned offset, int value)
79 81 {
80   - return set_gpio_flag(gp, GPIOF_HIGH, value);
  82 + return set_gpio_flag(dev, offset, GPIOF_HIGH, value);
81 83 }
82 84  
83   -int sandbox_gpio_get_direction(unsigned gp)
  85 +int sandbox_gpio_get_direction(struct device *dev, unsigned offset)
84 86 {
85   - return get_gpio_flag(gp, GPIOF_OUTPUT);
  87 + return get_gpio_flag(dev, offset, GPIOF_OUTPUT);
86 88 }
87 89  
88   -int sandbox_gpio_set_direction(unsigned gp, int output)
  90 +int sandbox_gpio_set_direction(struct device *dev, unsigned offset, int output)
89 91 {
90   - return set_gpio_flag(gp, GPIOF_OUTPUT, output);
  92 + return set_gpio_flag(dev, offset, GPIOF_OUTPUT, output);
91 93 }
92 94  
93 95 /*
94 96 * These functions implement the public interface within U-Boot
95 97 */
96 98  
97   -/* set GPIO port 'gp' as an input */
98   -int gpio_direction_input(unsigned gp)
  99 +/* set GPIO port 'offset' as an input */
  100 +static int sb_gpio_direction_input(struct device *dev, unsigned offset)
99 101 {
100   - debug("%s: gp:%u\n", __func__, gp);
  102 + debug("%s: offset:%u\n", __func__, offset);
101 103  
102   - if (check_reserved(gp, __func__))
  104 + if (check_reserved(dev, offset, __func__))
103 105 return -1;
104 106  
105   - return sandbox_gpio_set_direction(gp, 0);
  107 + return sandbox_gpio_set_direction(dev, offset, 0);
106 108 }
107 109  
108   -/* set GPIO port 'gp' as an output, with polarity 'value' */
109   -int gpio_direction_output(unsigned gp, int value)
  110 +/* set GPIO port 'offset' as an output, with polarity 'value' */
  111 +static int sb_gpio_direction_output(struct device *dev, unsigned offset,
  112 + int value)
110 113 {
111   - debug("%s: gp:%u, value = %d\n", __func__, gp, value);
  114 + debug("%s: offset:%u, value = %d\n", __func__, offset, value);
112 115  
113   - if (check_reserved(gp, __func__))
  116 + if (check_reserved(dev, offset, __func__))
114 117 return -1;
115 118  
116   - return sandbox_gpio_set_direction(gp, 1) |
117   - sandbox_gpio_set_value(gp, value);
  119 + return sandbox_gpio_set_direction(dev, offset, 1) |
  120 + sandbox_gpio_set_value(dev, offset, value);
118 121 }
119 122  
120   -/* read GPIO IN value of port 'gp' */
121   -int gpio_get_value(unsigned gp)
  123 +/* read GPIO IN value of port 'offset' */
  124 +static int sb_gpio_get_value(struct device *dev, unsigned offset)
122 125 {
123   - debug("%s: gp:%u\n", __func__, gp);
  126 + debug("%s: offset:%u\n", __func__, offset);
124 127  
125   - if (check_reserved(gp, __func__))
  128 + if (check_reserved(dev, offset, __func__))
126 129 return -1;
127 130  
128   - return sandbox_gpio_get_value(gp);
  131 + return sandbox_gpio_get_value(dev, offset);
129 132 }
130 133  
131   -/* write GPIO OUT value to port 'gp' */
132   -int gpio_set_value(unsigned gp, int value)
  134 +/* write GPIO OUT value to port 'offset' */
  135 +static int sb_gpio_set_value(struct device *dev, unsigned offset, int value)
133 136 {
134   - debug("%s: gp:%u, value = %d\n", __func__, gp, value);
  137 + debug("%s: offset:%u, value = %d\n", __func__, offset, value);
135 138  
136   - if (check_reserved(gp, __func__))
  139 + if (check_reserved(dev, offset, __func__))
137 140 return -1;
138 141  
139   - if (!sandbox_gpio_get_direction(gp)) {
140   - printf("sandbox_gpio: error: set_value on input gpio %u\n", gp);
  142 + if (!sandbox_gpio_get_direction(dev, offset)) {
  143 + printf("sandbox_gpio: error: set_value on input gpio %u\n",
  144 + offset);
141 145 return -1;
142 146 }
143 147  
144   - return sandbox_gpio_set_value(gp, value);
  148 + return sandbox_gpio_set_value(dev, offset, value);
145 149 }
146 150  
147   -int gpio_request(unsigned gp, const char *label)
  151 +static int sb_gpio_request(struct device *dev, unsigned offset,
  152 + const char *label)
148 153 {
149   - debug("%s: gp:%u, label:%s\n", __func__, gp, label);
  154 + struct gpio_dev_priv *uc_priv = dev->uclass_priv;
  155 + struct gpio_state *state = dev_get_priv(dev);
150 156  
151   - if (gp >= ARRAY_SIZE(state)) {
152   - printf("sandbox_gpio: error: invalid gpio %u\n", gp);
  157 + debug("%s: offset:%u, label:%s\n", __func__, offset, label);
  158 +
  159 + if (offset >= uc_priv->gpio_count) {
  160 + printf("sandbox_gpio: error: invalid gpio %u\n", offset);
153 161 return -1;
154 162 }
155 163  
156   - if (get_gpio_flag(gp, GPIOF_RESERVED)) {
157   - printf("sandbox_gpio: error: gpio %u already reserved\n", gp);
  164 + if (get_gpio_flag(dev, offset, GPIOF_RESERVED)) {
  165 + printf("sandbox_gpio: error: gpio %u already reserved\n",
  166 + offset);
158 167 return -1;
159 168 }
160 169  
161   - state[gp].label = label;
162   - return set_gpio_flag(gp, GPIOF_RESERVED, 1);
  170 + state[offset].label = label;
  171 + return set_gpio_flag(dev, offset, GPIOF_RESERVED, 1);
163 172 }
164 173  
165   -int gpio_free(unsigned gp)
  174 +static int sb_gpio_free(struct device *dev, unsigned offset)
166 175 {
167   - debug("%s: gp:%u\n", __func__, gp);
  176 + struct gpio_state *state = dev_get_priv(dev);
168 177  
169   - if (check_reserved(gp, __func__))
  178 + debug("%s: offset:%u\n", __func__, offset);
  179 +
  180 + if (check_reserved(dev, offset, __func__))
170 181 return -1;
171 182  
172   - state[gp].label = NULL;
173   - return set_gpio_flag(gp, GPIOF_RESERVED, 0);
  183 + state[offset].label = NULL;
  184 + return set_gpio_flag(dev, offset, GPIOF_RESERVED, 0);
174 185 }
175 186  
176   -/* Display GPIO information */
177   -void gpio_info(void)
  187 +static int sb_gpio_get_state(struct device *dev, unsigned int offset,
  188 + char *buf, int bufsize)
178 189 {
179   - unsigned gpio;
  190 + struct gpio_dev_priv *uc_priv = dev->uclass_priv;
  191 + struct gpio_state *state = dev_get_priv(dev);
  192 + const char *label;
180 193  
181   - puts("Sandbox GPIOs\n");
  194 + label = state[offset].label;
  195 + snprintf(buf, bufsize, "%s%d: %s: %d [%c]%s%s",
  196 + uc_priv->bank_name ? uc_priv->bank_name : "", offset,
  197 + sandbox_gpio_get_direction(dev, offset) ? "out" : " in",
  198 + sandbox_gpio_get_value(dev, offset),
  199 + get_gpio_flag(dev, offset, GPIOF_RESERVED) ? 'x' : ' ',
  200 + label ? " " : "",
  201 + label ? label : "");
182 202  
183   - for (gpio = 0; gpio < ARRAY_SIZE(state); ++gpio) {
184   - const char *label = state[gpio].label;
  203 + return 0;
  204 +}
185 205  
186   - printf("%4d: %s: %d [%c] %s\n",
187   - gpio,
188   - sandbox_gpio_get_direction(gpio) ? "out" : " in",
189   - sandbox_gpio_get_value(gpio),
190   - get_gpio_flag(gpio, GPIOF_RESERVED) ? 'x' : ' ',
191   - label ? label : "");
  206 +static const struct dm_gpio_ops gpio_sandbox_ops = {
  207 + .request = sb_gpio_request,
  208 + .free = sb_gpio_free,
  209 + .direction_input = sb_gpio_direction_input,
  210 + .direction_output = sb_gpio_direction_output,
  211 + .get_value = sb_gpio_get_value,
  212 + .set_value = sb_gpio_set_value,
  213 + .get_state = sb_gpio_get_state,
  214 +};
  215 +
  216 +static int sandbox_gpio_ofdata_to_platdata(struct device *dev)
  217 +{
  218 + struct gpio_dev_priv *uc_priv = dev->uclass_priv;
  219 +
  220 + uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
  221 + "num-gpios", 0);
  222 + uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
  223 + "gpio-bank-name", NULL);
  224 +
  225 + return 0;
  226 +}
  227 +
  228 +static int gpio_sandbox_probe(struct device *dev)
  229 +{
  230 + struct gpio_dev_priv *uc_priv = dev->uclass_priv;
  231 +
  232 + if (dev->of_offset == -1) {
  233 + /* Tell the uclass how many GPIOs we have */
  234 + uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT;
192 235 }
  236 +
  237 + dev->priv = calloc(sizeof(struct gpio_state), uc_priv->gpio_count);
  238 +
  239 + return 0;
193 240 }
  241 +
  242 +static const struct device_id sandbox_gpio_ids[] = {
  243 + { .compatible = "sandbox,gpio" },
  244 + { }
  245 +};
  246 +
  247 +U_BOOT_DRIVER(gpio_sandbox) = {
  248 + .name = "gpio_sandbox",
  249 + .id = UCLASS_GPIO,
  250 + .of_match = sandbox_gpio_ids,
  251 + .ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata,
  252 + .probe = gpio_sandbox_probe,
  253 + .ops = &gpio_sandbox_ops,
  254 +};
include/configs/sandbox.h
... ... @@ -26,6 +26,7 @@
26 26 #define CONFIG_DM_DEMO
27 27 #define CONFIG_DM_DEMO_SIMPLE
28 28 #define CONFIG_DM_DEMO_SHAPE
  29 +#define CONFIG_DM_GPIO
29 30 #define CONFIG_DM_TEST
30 31  
31 32 /* Number of bits in a C 'long' on this architecture */