Tobias Diedrich wrote:
> John Crispin wrote:
> > On 06/04/13 18:47, Tobias Diedrich wrote:
> > >+
> > >+ gpio-leds {
> > >+ compatible = "gpio-leds";
> > >+ // Used to enable power-over-ethernet passthrough from port0 to
> > >port1.
> > >+ // Disable passthrough by default to prevent accidental
> > >equipment damage.
> > >+ poe {
> > >+ label = "freestation:poe:passthrough";
> > >+ gpios =<&gpio0 11 1>;
> > >+ };
> > >+ // The following leds are defined in the ArcOS firmware, but
> > >reportedly
> > >+ // not present in the Freestation5 device.
> >
> > Hi,
> >
> > this should be done with an of_gpio_export node
> > ->
> > https://dev.openwrt.org/browser/trunk/target/linux/ramips/dts/DIR-645.dts#L134
>
> There's a bug in the gpio-export code. :)
>
> But I'm rewriting it to use the following syntax:
>
> gpio-export,name = "mario";
> gpio-export,flags = "out_init_high", "active_low", "changeable";
> gpio-export,gpios = <&gpio0 11 1>;
>
> Which will support the following flags (had to add GPIOF_ACTIVE_LOW):
>
> static struct of_gpio_flag of_gpio_flags[] = {
> { "in", GPIOF_DIR_IN },
> { "out_init_low", GPIOF_OUT_INIT_LOW },
> { "out_init_high", GPIOF_OUT_INIT_HIGH },
> { "open_drain", GPIOF_OPEN_DRAIN },
> { "open_source", GPIOF_OPEN_SOURCE },
> { "active_low", GPIOF_ACTIVE_LOW },
> { "changeable", GPIOF_EXPORT_CHANGEABLE },
> { /* sentinel */ }
> };
Something like this (WIP).
Also has a few consistency-changes:
- Changed gpio_export -> gpio-export for consistency with gpio-leds & friends.
- Changed gpio-export,name -> label for consistency
---
a/target/linux/ramips/patches-3.8/0209-owrt-GPIO-add-gpio_export_with_name.patch
+++
b/target/linux/ramips/patches-3.8/0209-owrt-GPIO-add-gpio_export_with_name.patch
@@ -91,7 +91,7 @@ Signed-off-by: John Crispin <blogic@open
/* Private data structure for of_gpiochip_find_and_xlate */
struct gg_data {
-@@ -289,3 +291,62 @@ void of_gpiochip_remove(struct gpio_chip
+@@ -289,3 +291,103 @@ void of_gpiochip_remove(struct gpio_chip
if (chip->of_node)
of_node_put(chip->of_node);
}
@@ -101,6 +101,32 @@ Signed-off-by: John Crispin <blogic@open
+ { /* sentinel */ }
+};
+
++/* Private data structure for of_gpio_flag_value */
++struct of_gpio_flag {
++ const char *name;
++ unsigned value;
++};
++
++static struct of_gpio_flag of_gpio_flags[] = {
++ { "in", GPIOF_DIR_IN },
++ { "out_init_low", GPIOF_OUT_INIT_LOW },
++ { "out_init_high", GPIOF_OUT_INIT_HIGH },
++ { "open_drain", GPIOF_OPEN_DRAIN },
++ { "open_source", GPIOF_OPEN_SOURCE },
++ { "active_low", GPIOF_ACTIVE_LOW },
++ { "changeable", GPIOF_EXPORT_CHANGEABLE },
++ { /* sentinel */ }
++};
++
++static unsigned __init of_gpio_flag_value(const char *name, struct
of_gpio_flag *flags)
++{
++ for (; flags->name; flags++)
++ if (!strcmp(flags->name, name))
++ return flags->value;
++
++ return 0;
++}
++
+static int __init of_gpio_export_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
@@ -111,27 +137,42 @@ Signed-off-by: John Crispin <blogic@open
+ for_each_child_of_node(np, cnp) {
+ const char *name = NULL;
+ int gpio;
-+ bool dmc;
+ int max_gpio = 1;
+ int i;
+
-+ of_property_read_string(cnp, "gpio-export,name", &name);
++ of_property_read_string(cnp, "label", &name);
+
+ if (!name)
+ max_gpio = of_gpio_count(cnp);
+
+ for (i = 0; i < max_gpio; i++) {
++ unsigned flags = GPIOF_EXPORT;
++ struct property *prop;
++ const char *flag;
++
+ gpio = of_get_gpio(cnp, i);
-+ if (devm_gpio_request(&pdev->dev, gpio, name ? name :
of_node_full_name(np)))
-+ continue;
+
-+ if (!of_property_read_u32(cnp, "gpio-export,output",
&val))
-+ gpio_direction_output(gpio, val);
-+ else
-+ gpio_direction_input(gpio);
++ /* Only use output/direction_may_change if flags isn't
used. */
++ if (!of_find_property(cnp, "gpio-export,flags", NULL)) {
++ if (!of_property_read_u32(cnp,
"gpio-export,output", &val)) {
++ if (val)
++ flags |= GPIOF_OUT_INIT_HIGH;
++ else
++ flags |= GPIOF_OUT_INIT_LOW;
++ } else {
++ flags |= GPIOF_DIR_IN;
++ }
++
++ if (of_property_read_bool(cnp,
"gpio-export,direction_may_change"))
++ flags |= GPIOF_EXPORT_CHANGEABLE;
++ }
++
++ of_property_for_each_string(cnp, "gpio-export,flags",
prop, flag)
++ flags |= of_gpio_flag_value(flag,
of_gpio_flags);
++
++ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name
? name : of_node_full_name(np)))
++ continue;
+
-+ dmc = of_property_read_bool(np,
"gpio-export,direction_may_change");
-+ gpio_export_with_name(gpio, dmc, name);
+ nb++;
+ }
+ }
@@ -156,9 +197,11 @@ Signed-off-by: John Crispin <blogic@open
+device_initcall(of_gpio_export_init);
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
-@@ -714,9 +714,10 @@ static struct class gpio_class = {
-
+@@ -712,11 +712,11 @@ static struct class gpio_class = {
+ .class_attrs = gpio_class_attrs,
+ };
+-
/**
- * gpio_export - export a GPIO through sysfs
+ * gpio_export_with_name - export a GPIO through sysfs
@@ -168,7 +211,7 @@ Signed-off-by: John Crispin <blogic@open
* Context: arch_initcall or later
*
* When drivers want to make a GPIO accessible to userspace after they
-@@ -728,7 +729,7 @@ static struct class gpio_class = {
+@@ -728,7 +728,7 @@ static struct class gpio_class = {
*
* Returns zero on success, else an error.
*/
@@ -177,16 +220,18 @@ Signed-off-by: John Crispin <blogic@open
{
unsigned long flags;
struct gpio_desc *desc;
-@@ -762,6 +763,8 @@ int gpio_export(unsigned gpio, bool dire
+@@ -762,6 +762,10 @@ int gpio_export(unsigned gpio, bool dire
goto fail_unlock;
}
+ if (name)
+ ioname = name;
++ if (!ioname && desc->label)
++ ioname = desc->label;
if (!desc->chip->direction_input || !desc->chip->direction_output)
direction_may_change = false;
spin_unlock_irqrestore(&gpio_lock, flags);
-@@ -804,7 +807,7 @@ fail_unlock:
+@@ -804,7 +808,7 @@ fail_unlock:
pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
return status;
}
@@ -195,6 +240,16 @@ Signed-off-by: John Crispin <blogic@open
static int match_export(struct device *dev, void *data)
{
+@@ -1418,6 +1422,9 @@ int gpio_request_one(unsigned gpio, unsi
+ if (flags & GPIOF_OPEN_SOURCE)
+ set_bit(FLAG_OPEN_SOURCE, &gpio_desc[gpio].flags);
+
++ if (flags & GPIOF_ACTIVE_LOW)
++ set_bit(FLAG_ACTIVE_LOW, &gpio_desc[gpio].flags);
++
+ if (flags & GPIOF_DIR_IN)
+ err = gpio_direction_input(gpio);
+ else
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -204,7 +204,8 @@ void devm_gpio_free(struct device *dev,
@@ -219,7 +274,17 @@ Signed-off-by: John Crispin <blogic@open
}
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
-@@ -189,7 +189,8 @@ static inline void gpio_set_value_cansle
+@@ -27,6 +27,9 @@
+ #define GPIOF_EXPORT_DIR_FIXED (GPIOF_EXPORT)
+ #define GPIOF_EXPORT_DIR_CHANGEABLE (GPIOF_EXPORT | GPIOF_EXPORT_CHANGEABLE)
+
++#define GPIOF_ACTIVE_HIGH (0 << 6)
++#define GPIOF_ACTIVE_LOW (1 << 6)
++
+ /**
+ * struct gpio - a structure describing a GPIO with configuration
+ * @gpio: the GPIO number
+@@ -189,7 +192,8 @@ static inline void gpio_set_value_cansle
WARN_ON(1);
}
@@ -229,7 +294,7 @@ Signed-off-by: John Crispin <blogic@open
{
/* GPIO can never have been requested or set as {in,out}put */
WARN_ON(1);
-@@ -248,4 +249,24 @@ gpiochip_remove_pin_ranges(struct gpio_c
+@@ -248,4 +252,24 @@ gpiochip_remove_pin_ranges(struct gpio_c
#endif /* ! CONFIG_GENERIC_GPIO */
--- a/target/linux/ramips/dts/DIR-645.dts
+++ b/target/linux/ramips/dts/DIR-645.dts
@@ -131,13 +131,13 @@
};
};
- gpio_export {
+ gpio-export {
compatible = "gpio-export";
#size-cells = <0>;
usb {
- gpio-export,name = "usb";
- gpio-export,output = <1>;
+ label = "usb";
+ gpio-export,flags = "out_init_high";
gpios = <&gpio1 6 0>;
};
};
--- a/target/linux/ramips/dts/OMNI-EMB-HPM.dts
+++ b/target/linux/ramips/dts/OMNI-EMB-HPM.dts
@@ -101,18 +101,18 @@
};
};
- gpio_export {
+ gpio-export {
compatible = "gpio-export";
#size-cells = <0>;
/* gpio 12 and 13 handle the OC input */
usb0 {
- gpio-export,name = "usb0";
- gpio-export,output = <1>;
+ label = "usb0";
+ gpio-export,flags = "out_init_high";
gpios = <&gpio0 2 0>;
};
usb1 {
- gpio-export,name = "usb1";
- gpio-export,output = <1>;
+ label = "usb1";
+ gpio-export,flags = "out_init_high";
gpios = <&gpio0 1 0>;
};
};
--- a/target/linux/ramips/dts/WR6202.dts
+++ b/target/linux/ramips/dts/WR6202.dts
@@ -85,13 +85,13 @@
status = "okay";
};
- gpio_export {
+ gpio-export {
compatible = "gpio-export";
#size-cells = <0>;
usb {
- gpio-export,name = "usb";
- gpio-export,output = <0>;
+ label = "usb";
+ gpio-export,flags = "out_init_low";
gpios = <&gpio0 11 0>;
};
};
--
Tobias PGP: http://8ef7ddba.uguu.de
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/mailman/listinfo/openwrt-devel