X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/9b9f950511f1b7fdb769ebeb4cfa24c31ecfca49..9fa649271dbc9c83417488203aeb1668a0238c54:/target/linux/generic-2.6/patches-2.6.26/980-backport_gpio_sysfs_support.patch diff --git a/target/linux/generic-2.6/patches-2.6.26/980-backport_gpio_sysfs_support.patch b/target/linux/generic-2.6/patches-2.6.26/980-backport_gpio_sysfs_support.patch index 44d126c4c..efacb2512 100644 --- a/target/linux/generic-2.6/patches-2.6.26/980-backport_gpio_sysfs_support.patch +++ b/target/linux/generic-2.6/patches-2.6.26/980-backport_gpio_sysfs_support.patch @@ -70,7 +70,7 @@ Signed-off-by: Linus Torvalds --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt -@@ -347,15 +347,12 @@ +@@ -347,15 +347,12 @@ necessarily be nonportable. Dynamic definition of GPIOs is not currently standard; for example, as a side effect of configuring an add-on board with some GPIO expanders. @@ -87,7 +87,7 @@ Signed-off-by: Linus Torvalds As a debugging aid, if debugfs is available a /sys/kernel/debug/gpio file will be found there. That will list all the controllers registered through -@@ -439,4 +436,120 @@ +@@ -439,4 +436,120 @@ becomes available. That may mean the de calls for that GPIO can work. One way to address such dependencies is for such gpio_chip controllers to provide setup() and teardown() callbacks to board specific code; those board specific callbacks would register devices @@ -211,7 +211,7 @@ Signed-off-by: Linus Torvalds +suitable for documenting as part of a board support package. --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c -@@ -1488,6 +1488,9 @@ +@@ -1488,6 +1488,9 @@ static int __init _omap_gpio_init(void) bank->chip.set = gpio_set; if (bank_is_mpuio(bank)) { bank->chip.label = "mpuio"; @@ -223,7 +223,7 @@ Signed-off-by: Linus Torvalds bank->chip.label = "gpio"; --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c -@@ -358,6 +358,8 @@ +@@ -358,6 +358,8 @@ static int __init pio_probe(struct platf pio->chip.label = pio->name; pio->chip.base = pdev->id * 32; pio->chip.ngpio = 32; @@ -234,7 +234,7 @@ Signed-off-by: Linus Torvalds pio->chip.get = gpio_get; --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig -@@ -23,6 +23,21 @@ +@@ -23,6 +23,21 @@ config DEBUG_GPIO slower. The diagnostics help catch the type of setup errors that are most common when setting up new platforms or boards. @@ -272,7 +272,7 @@ Signed-off-by: Linus Torvalds /* Optional implementation infrastructure for GPIO interfaces. -@@ -44,6 +47,8 @@ +@@ -44,6 +47,8 @@ struct gpio_desc { #define FLAG_REQUESTED 0 #define FLAG_IS_OUT 1 #define FLAG_RESERVED 2 @@ -281,7 +281,7 @@ Signed-off-by: Linus Torvalds #ifdef CONFIG_DEBUG_FS const char *label; -@@ -151,6 +156,482 @@ +@@ -151,6 +156,486 @@ err: return ret; } @@ -558,7 +558,7 @@ Signed-off-by: Linus Torvalds + int status = -EINVAL; + + /* can't export until sysfs is available ... */ -+ if (!gpio_class.p) { ++ if (!gpio_class.subsys.kobj.ktype) { + pr_debug("%s: called too early!\n", __func__); + return -ENOENT; + } @@ -583,8 +583,9 @@ Signed-off-by: Linus Torvalds + struct device *dev; + + dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), -+ desc, "gpio%d", gpio); ++ "gpio%d", gpio); + if (dev) { ++ dev_set_drvdata(dev, desc); + if (direction_may_change) + status = sysfs_create_group(&dev->kobj, + &gpio_attr_group); @@ -634,8 +635,9 @@ Signed-off-by: Linus Torvalds + if (test_bit(FLAG_EXPORT, &desc->flags)) { + struct device *dev = NULL; + -+ dev = class_find_device(&gpio_class, NULL, desc, match_export); ++ dev = class_find_device(&gpio_class, desc, match_export); + if (dev) { ++ dev_set_drvdata(dev, NULL); + clear_bit(FLAG_EXPORT, &desc->flags); + put_device(dev); + device_unregister(dev); @@ -661,14 +663,15 @@ Signed-off-by: Linus Torvalds + * export this later, in gpiolib_sysfs_init() ... here we just + * verify that _some_ field of gpio_class got initialized. + */ -+ if (!gpio_class.p) ++ if (!gpio_class.subsys.kobj.ktype) + return 0; + + /* use chip->base for the ID; it's already known to be unique */ + mutex_lock(&sysfs_lock); -+ dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip, ++ dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), + "gpiochip%d", chip->base); + if (dev) { ++ dev_set_drvdata(dev, chip); + status = sysfs_create_group(&dev->kobj, + &gpiochip_attr_group); + } else @@ -699,8 +702,9 @@ Signed-off-by: Linus Torvalds + struct device *dev; + + mutex_lock(&sysfs_lock); -+ dev = class_find_device(&gpio_class, NULL, chip, match_export); ++ dev = class_find_device(&gpio_class, chip, match_export); + if (dev) { ++ dev_set_drvdata(dev, NULL); + put_device(dev); + device_unregister(dev); + chip->exported = 0; @@ -764,7 +768,7 @@ Signed-off-by: Linus Torvalds /** * gpiochip_add() - register a gpio_chip * @chip: the chip to register, with chip->base initialized -@@ -160,6 +641,11 @@ +@@ -160,6 +645,11 @@ err: * because the chip->base is invalid or already associated with a * different chip. Otherwise it returns zero as a success code. * @@ -776,7 +780,7 @@ Signed-off-by: Linus Torvalds * If chip->base is negative, this requests dynamic assignment of * a range of valid GPIOs. */ -@@ -182,7 +668,7 @@ +@@ -182,7 +672,7 @@ int gpiochip_add(struct gpio_chip *chip) base = gpiochip_find_base(chip->ngpio); if (base < 0) { status = base; @@ -785,7 +789,7 @@ Signed-off-by: Linus Torvalds } chip->base = base; } -@@ -197,12 +683,23 @@ +@@ -197,12 +687,23 @@ int gpiochip_add(struct gpio_chip *chip) if (status == 0) { for (id = base; id < base + chip->ngpio; id++) { gpio_desc[id].chip = chip; @@ -811,7 +815,7 @@ Signed-off-by: Linus Torvalds fail: /* failures here can mean systems won't boot... */ if (status) -@@ -239,6 +736,10 @@ +@@ -239,6 +740,10 @@ int gpiochip_remove(struct gpio_chip *ch } spin_unlock_irqrestore(&gpio_lock, flags); @@ -822,7 +826,7 @@ Signed-off-by: Linus Torvalds return status; } EXPORT_SYMBOL_GPL(gpiochip_remove); -@@ -296,6 +797,8 @@ +@@ -296,6 +801,8 @@ void gpio_free(unsigned gpio) return; } @@ -831,7 +835,7 @@ Signed-off-by: Linus Torvalds spin_lock_irqsave(&gpio_lock, flags); desc = &gpio_desc[gpio]; -@@ -534,10 +1037,6 @@ +@@ -534,10 +1041,6 @@ EXPORT_SYMBOL_GPL(gpio_set_value_canslee #ifdef CONFIG_DEBUG_FS @@ -842,7 +846,7 @@ Signed-off-by: Linus Torvalds static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) { unsigned i; -@@ -614,17 +1113,28 @@ +@@ -614,17 +1117,28 @@ static int gpiolib_show(struct seq_file /* REVISIT this isn't locked against gpio_chip removal ... */ for (gpio = 0; gpio_is_valid(gpio); gpio++) { @@ -877,7 +881,7 @@ Signed-off-by: Linus Torvalds chip->dbg_show(s, chip); --- a/drivers/gpio/mcp23s08.c +++ b/drivers/gpio/mcp23s08.c -@@ -239,6 +239,7 @@ +@@ -239,6 +239,7 @@ static int mcp23s08_probe(struct spi_dev mcp->chip.base = pdata->base; mcp->chip.ngpio = 8; mcp->chip.can_sleep = 1; @@ -887,7 +891,7 @@ Signed-off-by: Linus Torvalds spi_set_drvdata(spi, mcp); --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c -@@ -188,6 +188,7 @@ +@@ -188,6 +188,7 @@ static void pca953x_setup_gpio(struct pc gc->base = chip->gpio_start; gc->ngpio = gpios; gc->label = chip->client->name; @@ -897,7 +901,7 @@ Signed-off-by: Linus Torvalds --- a/drivers/gpio/pcf857x.c +++ b/drivers/gpio/pcf857x.c -@@ -175,6 +175,7 @@ +@@ -175,6 +175,7 @@ static int pcf857x_probe(struct i2c_clie gpio->chip.base = pdata->gpio_base; gpio->chip.can_sleep = 1; @@ -907,7 +911,7 @@ Signed-off-by: Linus Torvalds /* NOTE: the OnSemi jlc1562b is also largely compatible with --- a/drivers/i2c/chips/tps65010.c +++ b/drivers/i2c/chips/tps65010.c -@@ -636,6 +636,8 @@ +@@ -636,6 +636,8 @@ static int tps65010_probe(struct i2c_cli tps->outmask = board->outmask; tps->chip.label = client->name; @@ -918,7 +922,7 @@ Signed-off-by: Linus Torvalds tps->chip.direction_output = tps65010_output; --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c -@@ -318,6 +318,8 @@ +@@ -318,6 +318,8 @@ static int __init egpio_probe(struct pla ei->chip[i].dev = &(pdev->dev); chip = &(ei->chip[i].chip); chip->label = "htc-egpio"; @@ -929,7 +933,7 @@ Signed-off-by: Linus Torvalds chip->direction_input = egpio_direction_input; --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h -@@ -32,6 +32,8 @@ +@@ -32,6 +32,8 @@ struct module; /** * struct gpio_chip - abstract a GPIO controller * @label: for diagnostics @@ -938,7 +942,7 @@ Signed-off-by: Linus Torvalds * @direction_input: configures signal "offset" as input, or returns error * @get: returns value for signal "offset"; for output signals this * returns either the value actually sensed, or zero -@@ -59,6 +61,7 @@ +@@ -59,6 +61,7 @@ struct module; */ struct gpio_chip { char *label; @@ -946,7 +950,7 @@ Signed-off-by: Linus Torvalds struct module *owner; int (*direction_input)(struct gpio_chip *chip, -@@ -74,6 +77,7 @@ +@@ -74,6 +77,7 @@ struct gpio_chip { int base; u16 ngpio; unsigned can_sleep:1; @@ -954,7 +958,7 @@ Signed-off-by: Linus Torvalds }; extern const char *gpiochip_is_requested(struct gpio_chip *chip, -@@ -108,7 +112,18 @@ +@@ -108,7 +112,18 @@ extern void __gpio_set_value(unsigned gp extern int __gpio_cansleep(unsigned gpio); @@ -974,7 +978,7 @@ Signed-off-by: Linus Torvalds static inline int gpio_is_valid(int number) { -@@ -137,6 +152,20 @@ +@@ -137,6 +152,22 @@ static inline void gpio_set_value_cansle gpio_set_value(gpio, value); } @@ -983,6 +987,8 @@ Signed-off-by: Linus Torvalds + +#ifndef CONFIG_GPIO_SYSFS + ++#include ++ +/* sysfs support is only available with gpiolib, where it's optional */ + +static inline int gpio_export(unsigned gpio, bool direction_may_change) @@ -998,7 +1004,7 @@ Signed-off-by: Linus Torvalds #endif /* _ASM_GENERIC_GPIO_H */ --- a/include/linux/gpio.h +++ b/include/linux/gpio.h -@@ -79,6 +79,19 @@ +@@ -79,6 +79,19 @@ static inline void gpio_set_value_cansle WARN_ON(1); }