From: Florian Fainelli Date: Fri, 11 Dec 2009 19:32:52 +0000 (+0000) Subject: convert gpio code to use gpiolib, make rdc321x:dmz led work again X-Git-Tag: reboot~21678 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=95fa0702028d0aa0ffb625e5fd08e90d76d4290f;p=openwrt%2Fopenwrt.git convert gpio code to use gpiolib, make rdc321x:dmz led work again SVN-Revision: 18754 --- diff --git a/target/linux/rdc/config-2.6.30 b/target/linux/rdc/config-2.6.30 index 0113a58dbd..52a5d07223 100644 --- a/target/linux/rdc/config-2.6.30 +++ b/target/linux/rdc/config-2.6.30 @@ -75,6 +75,10 @@ CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_FIND_FIRST_BIT=y CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_GPIO=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +CONFIG_LEDS_GPIO=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_IOMAP=y CONFIG_GENERIC_ISA_DMA=y diff --git a/target/linux/rdc/files-2.6.30/arch/x86/include/asm/rdc321x_gpio.h b/target/linux/rdc/files-2.6.30/arch/x86/include/asm/rdc321x_gpio.h index 873bffe302..adb75aff27 100644 --- a/target/linux/rdc/files-2.6.30/arch/x86/include/asm/rdc321x_gpio.h +++ b/target/linux/rdc/files-2.6.30/arch/x86/include/asm/rdc321x_gpio.h @@ -3,55 +3,12 @@ #include -extern int rdc_gpio_get_value(unsigned gpio); -extern void rdc_gpio_set_value(unsigned gpio, int value); -extern int rdc_gpio_direction_input(unsigned gpio); -extern int rdc_gpio_direction_output(unsigned gpio, int value); -extern int rdc_gpio_request(unsigned gpio, const char *label); -extern void rdc_gpio_free(unsigned gpio); +#define gpio_to_irq(gpio) NULL -/* Wrappers for the arch-neutral GPIO API */ +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value -static inline int gpio_request(unsigned gpio, const char *label) -{ - return rdc_gpio_request(gpio, label); -} - -static inline void gpio_free(unsigned gpio) -{ - might_sleep(); - rdc_gpio_free(gpio); -} - -static inline int gpio_direction_input(unsigned gpio) -{ - return rdc_gpio_direction_input(gpio); -} - -static inline int gpio_direction_output(unsigned gpio, int value) -{ - return rdc_gpio_direction_output(gpio, value); -} - -static inline int gpio_get_value(unsigned gpio) -{ - return rdc_gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - rdc_gpio_set_value(gpio, value); -} - -static inline int gpio_to_irq(unsigned gpio) -{ - return gpio; -} - -static inline int irq_to_gpio(unsigned irq) -{ - return irq; -} +#define gpio_cansleep __gpio_cansleep /* For cansleep */ #include diff --git a/target/linux/rdc/files-2.6.30/arch/x86/mach-rdc321x/gpio.c b/target/linux/rdc/files-2.6.30/arch/x86/mach-rdc321x/gpio.c index 92df2201df..c99b3b2239 100644 --- a/target/linux/rdc/files-2.6.30/arch/x86/mach-rdc321x/gpio.c +++ b/target/linux/rdc/files-2.6.30/arch/x86/mach-rdc321x/gpio.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,9 +39,6 @@ static DEFINE_SPINLOCK(gpio_lock); static u32 gpio_data_reg1; static u32 gpio_data_reg2; -static u32 gpio_request_data[2]; - - static inline void rdc321x_conf_write(unsigned addr, u32 value) { outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR); @@ -73,63 +71,8 @@ static void rdc321x_configure_gpio(unsigned gpio) spin_unlock_irqrestore(&gpio_lock, flags); } -/* initially setup the 2 copies of the gpio data registers. - This function is called before the platform setup code. */ -static int __init rdc321x_gpio_setup(void) -{ - /* this might not be, what others (BIOS, bootloader, etc.) - wrote to these registers before, but it's a good guess. Still - better than just using 0xffffffff. */ - - gpio_data_reg1 = rdc321x_conf_read(RDC321X_GPIO_DATA_REG1); - gpio_data_reg2 = rdc321x_conf_read(RDC321X_GPIO_DATA_REG2); - - return 0; -} - -/* determine, if gpio number is valid */ -static inline int rdc321x_is_gpio(unsigned gpio) -{ - return gpio <= RDC321X_MAX_GPIO; -} - -/* request GPIO */ -int rdc_gpio_request(unsigned gpio, const char *label) -{ - unsigned long flags; - - if (!rdc321x_is_gpio(gpio)) - return -EINVAL; - - spin_lock_irqsave(&gpio_lock, flags); - if (gpio_request_data[(gpio & 0x20) ? 1 : 0] & (1 << (gpio & 0x1f))) - goto inuse; - gpio_request_data[(gpio & 0x20) ? 1 : 0] |= (1 << (gpio & 0x1f)); - spin_unlock_irqrestore(&gpio_lock, flags); - - return 0; -inuse: - spin_unlock_irqrestore(&gpio_lock, flags); - return -EINVAL; -} -EXPORT_SYMBOL(rdc_gpio_request); - -/* release previously-claimed GPIO */ -void rdc_gpio_free(unsigned gpio) -{ - unsigned long flags; - - if (!rdc321x_is_gpio(gpio)) - return; - - spin_lock_irqsave(&gpio_lock, flags); - gpio_request_data[(gpio & 0x20) ? 1 : 0] &= ~(1 << (gpio & 0x1f)); - spin_unlock_irqrestore(&gpio_lock, flags); -} -EXPORT_SYMBOL(rdc_gpio_free); - /* read GPIO pin */ -int rdc_gpio_get_value(unsigned gpio) +static int rdc_gpio_get_value(struct gpio_chip *chip, unsigned gpio) { u32 reg; unsigned long flags; @@ -141,10 +84,10 @@ int rdc_gpio_get_value(unsigned gpio) return (1 << (gpio & 0x1f)) & reg ? 1 : 0; } -EXPORT_SYMBOL(rdc_gpio_get_value); /* set GPIO pin to value */ -void rdc_gpio_set_value(unsigned gpio, int value) +static void rdc_gpio_set_value(struct gpio_chip *chip, + unsigned gpio, int value) { unsigned long flags; u32 reg; @@ -168,31 +111,48 @@ void rdc_gpio_set_value(unsigned gpio, int value) spin_unlock_irqrestore(&gpio_lock, flags); } } -EXPORT_SYMBOL(rdc_gpio_set_value); /* configure GPIO pin as input */ -int rdc_gpio_direction_input(unsigned gpio) +static int rdc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) { - if (!rdc321x_is_gpio(gpio)) - return -EINVAL; - rdc321x_configure_gpio(gpio); return 0; } -EXPORT_SYMBOL(rdc_gpio_direction_input); /* configure GPIO pin as output and set value */ -int rdc_gpio_direction_output(unsigned gpio, int value) +static int rdc_gpio_direction_output(struct gpio_chip *chip, + unsigned gpio, int value) { - if (!rdc321x_is_gpio(gpio)) - return -EINVAL; - - gpio_set_value(gpio, value); rdc321x_configure_gpio(gpio); + gpio_set_value(gpio, value); return 0; } -EXPORT_SYMBOL(rdc_gpio_direction_output); + +static struct gpio_chip rdc321x_gpio_chip = { + .label = "rdc321x-gpio", + .direction_input = rdc_gpio_direction_input, + .direction_output = rdc_gpio_direction_output, + .get = rdc_gpio_get_value, + .set = rdc_gpio_set_value, + .base = 0, + .ngpio = RDC321X_MAX_GPIO, +}; + +/* initially setup the 2 copies of the gpio data registers. + This function is called before the platform setup code. */ +static int __init rdc321x_gpio_setup(void) +{ + /* this might not be, what others (BIOS, bootloader, etc.) + wrote to these registers before, but it's a good guess. Still + better than just using 0xffffffff. */ + + gpio_data_reg1 = rdc321x_conf_read(RDC321X_GPIO_DATA_REG1); + gpio_data_reg2 = rdc321x_conf_read(RDC321X_GPIO_DATA_REG2); + + printk(KERN_INFO "rdc321x: registering %d GPIOs\n", rdc321x_gpio_chip.ngpio); + return gpiochip_add(&rdc321x_gpio_chip); +} arch_initcall(rdc321x_gpio_setup); diff --git a/target/linux/rdc/files-2.6.30/arch/x86/mach-rdc321x/platform.c b/target/linux/rdc/files-2.6.30/arch/x86/mach-rdc321x/platform.c index f59cb15a7c..3c2cec721a 100644 --- a/target/linux/rdc/files-2.6.30/arch/x86/mach-rdc321x/platform.c +++ b/target/linux/rdc/files-2.6.30/arch/x86/mach-rdc321x/platform.c @@ -79,7 +79,7 @@ static struct platform_device rdc_flash_device = { /* LEDS */ static struct gpio_led default_leds[] = { - { .name = "rdc321x:dmz", .gpio = 1, }, + { .name = "rdc321x:dmz", .gpio = 1, .active_low = 1}, }; static struct gpio_led_platform_data rdc321x_led_data = { diff --git a/target/linux/rdc/patches-2.6.30/009-rdc321x_select_embedded.patch b/target/linux/rdc/patches-2.6.30/009-rdc321x_select_embedded.patch index 0e0e1192b3..f92fd61080 100644 --- a/target/linux/rdc/patches-2.6.30/009-rdc321x_select_embedded.patch +++ b/target/linux/rdc/patches-2.6.30/009-rdc321x_select_embedded.patch @@ -1,10 +1,11 @@ --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -380,6 +380,7 @@ config X86_RDC321X +@@ -380,6 +380,8 @@ config X86_RDC321X depends on X86_EXTENDED_PLATFORM select M486 select X86_REBOOTFIXUPS + select EMBEDDED ++ select ARCH_REQUIRE_GPIOLIB ---help--- This option is needed for RDC R-321x system-on-chip, also known as R-8610-(G).