Commit 141e1faec2cd594dafb2edad6da8baa6a681cf37

Authored by Tom Rini

Merge git://git.denx.de/u-boot-dm

Showing 3 changed files Side-by-side Diff

arch/sandbox/dts/sandbox.dts
... ... @@ -113,5 +113,13 @@
113 113 0x070b0067 0x070c0069>;
114 114 };
115 115  
  116 + gpio_a: gpios {
  117 + gpio-controller;
  118 + compatible = "sandbox,gpio";
  119 + #gpio-cells = <1>;
  120 + gpio-bank-name = "a";
  121 + num-gpios = <20>;
  122 + };
  123 +
116 124 };
... ... @@ -8,6 +8,7 @@
8 8  
9 9 #include <common.h>
10 10 #include <command.h>
  11 +#include <errno.h>
11 12 #include <dm.h>
12 13 #include <asm/gpio.h>
13 14  
14 15  
15 16  
16 17  
17 18  
18 19  
... ... @@ -24,18 +25,46 @@
24 25 };
25 26  
26 27 #if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
27   -static const char * const gpio_function[] = {
  28 +static const char * const gpio_function[GPIOF_COUNT] = {
28 29 "input",
29 30 "output",
  31 + "unused",
30 32 "unknown",
  33 + "func",
31 34 };
32 35  
33   -static void show_gpio(struct udevice *dev, const char *bank_name, int offset)
  36 +/* A few flags used by show_gpio() */
  37 +enum {
  38 + FLAG_SHOW_ALL = 1 << 0,
  39 + FLAG_SHOW_BANK = 1 << 1,
  40 + FLAG_SHOW_NEWLINE = 1 << 2,
  41 +};
  42 +
  43 +static void show_gpio(struct udevice *dev, const char *bank_name, int offset,
  44 + int *flagsp)
34 45 {
35 46 struct dm_gpio_ops *ops = gpio_get_ops(dev);
  47 + int func = GPIOF_UNKNOWN;
36 48 char buf[80];
37 49 int ret;
38 50  
  51 + BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
  52 +
  53 + if (ops->get_function) {
  54 + ret = ops->get_function(dev, offset);
  55 + if (ret >= 0 && ret < ARRAY_SIZE(gpio_function))
  56 + func = ret;
  57 + }
  58 + if (!(*flagsp & FLAG_SHOW_ALL) && func == GPIOF_UNUSED)
  59 + return;
  60 + if ((*flagsp & FLAG_SHOW_BANK) && bank_name) {
  61 + if (*flagsp & FLAG_SHOW_NEWLINE) {
  62 + putc('\n');
  63 + *flagsp &= ~FLAG_SHOW_NEWLINE;
  64 + }
  65 + printf("Bank %s:\n", bank_name);
  66 + *flagsp &= ~FLAG_SHOW_BANK;
  67 + }
39 68 *buf = '\0';
40 69 if (ops->get_state) {
41 70 ret = ops->get_state(dev, offset, buf, sizeof(buf));
... ... @@ -44,14 +73,6 @@
44 73 return;
45 74 }
46 75 } else {
47   - int func = GPIOF_UNKNOWN;
48   - int ret;
49   -
50   - if (ops->get_function) {
51   - ret = ops->get_function(dev, offset);
52   - if (ret >= 0 && ret < ARRAY_SIZE(gpio_function))
53   - func = ret;
54   - }
55 76 sprintf(buf, "%s%u: %8s %d", bank_name, offset,
56 77 gpio_function[func], ops->get_value(dev, offset));
57 78 }
58 79  
59 80  
... ... @@ -60,12 +81,14 @@
60 81 puts("\n");
61 82 }
62 83  
63   -static int do_gpio_status(const char *gpio_name)
  84 +static int do_gpio_status(bool all, const char *gpio_name)
64 85 {
65 86 struct udevice *dev;
66   - int newline = 0;
  87 + int banklen;
  88 + int flags;
67 89 int ret;
68 90  
  91 + flags = 0;
69 92 if (gpio_name && !*gpio_name)
70 93 gpio_name = NULL;
71 94 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
72 95  
73 96  
74 97  
75 98  
76 99  
77 100  
... ... @@ -74,28 +97,33 @@
74 97 const char *bank_name;
75 98 int num_bits;
76 99  
  100 + flags |= FLAG_SHOW_BANK;
  101 + if (all)
  102 + flags |= FLAG_SHOW_ALL;
77 103 bank_name = gpio_get_bank_info(dev, &num_bits);
  104 + if (!num_bits)
  105 + continue;
  106 + banklen = bank_name ? strlen(bank_name) : 0;
78 107  
79 108 if (!gpio_name || !bank_name ||
80   - !strncmp(gpio_name, bank_name, strlen(bank_name))) {
  109 + !strncmp(gpio_name, bank_name, banklen)) {
81 110 const char *p = NULL;
82 111 int offset;
83 112  
84   - if (bank_name) {
85   - if (newline)
86   - putc('\n');
87   - printf("Bank %s:\n", bank_name);
88   - }
89   - newline = 1;
90   - if (gpio_name && bank_name) {
91   - p = gpio_name + strlen(bank_name);
  113 + p = gpio_name + banklen;
  114 + if (gpio_name && *p) {
92 115 offset = simple_strtoul(p, NULL, 10);
93   - show_gpio(dev, bank_name, offset);
  116 + show_gpio(dev, bank_name, offset, &flags);
94 117 } else {
95   - for (offset = 0; offset < num_bits; offset++)
96   - show_gpio(dev, bank_name, offset);
  118 + for (offset = 0; offset < num_bits; offset++) {
  119 + show_gpio(dev, bank_name, offset,
  120 + &flags);
  121 + }
97 122 }
98 123 }
  124 + /* Add a newline between bank names */
  125 + if (!(flags & FLAG_SHOW_BANK))
  126 + flags |= FLAG_SHOW_NEWLINE;
99 127 }
100 128  
101 129 return ret;
102 130  
103 131  
104 132  
... ... @@ -108,23 +136,33 @@
108 136 enum gpio_cmd sub_cmd;
109 137 ulong value;
110 138 const char *str_cmd, *str_gpio = NULL;
111   -#ifdef CONFIG_DM_GPIO
112 139 int ret;
  140 +#ifdef CONFIG_DM_GPIO
  141 + bool all = false;
113 142 #endif
114 143  
115 144 if (argc < 2)
116 145 show_usage:
117 146 return CMD_RET_USAGE;
118 147 str_cmd = argv[1];
119   - if (argc > 2)
120   - str_gpio = argv[2];
  148 + argc -= 2;
  149 + argv += 2;
  150 +#ifdef CONFIG_DM_GPIO
  151 + if (argc > 0 && !strcmp(*argv, "-a")) {
  152 + all = true;
  153 + argc--;
  154 + argv++;
  155 + }
  156 +#endif
  157 + if (argc > 0)
  158 + str_gpio = *argv;
121 159 if (!strcmp(str_cmd, "status")) {
122 160 /* Support deprecated gpio_status() */
123 161 #ifdef gpio_status
124 162 gpio_status();
125 163 return 0;
126 164 #elif defined(CONFIG_DM_GPIO)
127   - return cmd_process_error(cmdtp, do_gpio_status(str_gpio));
  165 + return cmd_process_error(cmdtp, do_gpio_status(all, str_gpio));
128 166 #else
129 167 goto show_usage;
130 168 #endif
... ... @@ -160,7 +198,8 @@
160 198 goto show_usage;
161 199 #endif
162 200 /* grab the pin before we tweak it */
163   - if (gpio_request(gpio, "cmd_gpio")) {
  201 + ret = gpio_request(gpio, "cmd_gpio");
  202 + if (ret && ret != -EBUSY) {
164 203 printf("gpio: requesting pin %u failed\n", gpio);
165 204 return -1;
166 205 }
167 206  
... ... @@ -181,14 +220,15 @@
181 220 printf("gpio: pin %s (gpio %i) value is %lu\n",
182 221 str_gpio, gpio, value);
183 222  
184   - gpio_free(gpio);
  223 + if (ret != -EBUSY)
  224 + gpio_free(gpio);
185 225  
186 226 return value;
187 227 }
188 228  
189   -U_BOOT_CMD(gpio, 3, 0, do_gpio,
190   - "query and control gpio pins",
191   - "<input|set|clear|toggle> <pin>\n"
192   - " - input/set/clear/toggle the specified pin\n"
193   - "gpio status [<bank> | <pin>]");
  229 +U_BOOT_CMD(gpio, 4, 0, do_gpio,
  230 + "query and control gpio pins",
  231 + "<input|set|clear|toggle> <pin>\n"
  232 + " - input/set/clear/toggle the specified pin\n"
  233 + "gpio status [-a] [<bank> | <pin>] - show [all/claimed] GPIOs");
include/asm-generic/gpio.h
... ... @@ -79,11 +79,15 @@
79 79 */
80 80 int gpio_set_value(unsigned gpio, int value);
81 81  
82   -/* State of a GPIO, as reported by get_state() */
  82 +/* State of a GPIO, as reported by get_function() */
83 83 enum {
84 84 GPIOF_INPUT = 0,
85 85 GPIOF_OUTPUT,
86   - GPIOF_UNKNOWN,
  86 + GPIOF_UNUSED, /* Not claimed */
  87 + GPIOF_UNKNOWN, /* Not known */
  88 + GPIOF_FUNC, /* Not used as a GPIO */
  89 +
  90 + GPIOF_COUNT,
87 91 };
88 92  
89 93 struct udevice;
... ... @@ -123,6 +127,13 @@
123 127 int value);
124 128 int (*get_value)(struct udevice *dev, unsigned offset);
125 129 int (*set_value)(struct udevice *dev, unsigned offset, int value);
  130 + /**
  131 + * get_function() Get the GPIO function
  132 + *
  133 + * @dev: Device to check
  134 + * @offset: GPIO offset within that device
  135 + * @return current function - GPIOF_...
  136 + */
126 137 int (*get_function)(struct udevice *dev, unsigned offset);
127 138 int (*get_state)(struct udevice *dev, unsigned offset, char *state,
128 139 int maxlen);