ARM: OMAP: GPIO code updates shared between OMAP1 and OMAP2
Subsystems (3)
Tony Lindgren
reviewercover ARM: OMAP: GPIO code updates shared between OMAP1 and OMAP2
Hi,
The following patch series contains GPIO updates for OMAP.
This is take #2 of the earlier 90 patch mountain, which has been split into six smaller series.
Regards,
Tony
Tony Lindgren
reviewerPATCH 1/10 ARM: OMAP: Enable 24xx GPIO autoidling
From: Juha Yrjola <[email protected]>
Enable 24xx GPIO autoidling
--- arch/arm/plat-omap/gpio.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
arch/arm/plat-omap/gpio.c +10 -0
@@ -1083,6 +1083,10 @@ static int __init _omap_gpio_init(void)if (bank->method ==METHOD_GPIO_24XX ) {__raw_writel (0x00000000 , bank->base +OMAP24XX_GPIO_IRQENABLE1 );__raw_writel (0xffffffff , bank->base +OMAP24XX_GPIO_IRQSTATUS1 ); +__raw_writew (0x0015 , bank->base +OMAP24XX_GPIO_SYSCONFIG ); + +/* Initialize interface clock ungated, module enabled */ +__raw_writel (0 , bank->base +OMAP24XX_GPIO_CTRL ); gpio_count =32 ; }
@@ -1105,6 +1109,12 @@ static int __init _omap_gpio_init(void)if (cpu_is_omap16xx ())omap_writel (omap_readl (ULPD_CAM_CLK_CTRL ) |0x04 ,ULPD_CAM_CLK_CTRL ); +#ifdef CONFIG_ARCH_OMAP24XX +/* Enable autoidle for the OCP interface */ +if (cpu_is_omap24xx ()) +omap_writel (1 <<0 ,0x48019010 ); +#endif +return 0 ; }
Signature · 1 line
1.4.4.2
Tony Lindgren
reviewerPATCH 2/10 ARM: OMAP: Implement workaround for GPIO wakeup bug in OMAP2420 silicon
From: Juha Yrjola <[email protected]>
Some GPIOs on OMAP2420 do not have wakeup capabilities. If these GPIOs are configured as IRQ sources, spurious interrupts will be generated each time the core domain enters retention.
--- arch/arm/plat-omap/gpio.c | 154 +++++++++++++++++++++++++++++++++++++++----- 1 files changed, 136 insertions(+), 18 deletions(-)
arch/arm/plat-omap/gpio.c +136 -18
@@ -118,8 +118,18 @@ struct gpio_bank {u16 virtual_irq_start;int method;u32 reserved_map; +#if defined (CONFIG_ARCH_OMAP16XX ) || defined (CONFIG_ARCH_OMAP24XX )u32 suspend_wakeup;u32 saved_wakeup; +#endif +#ifdef CONFIG_ARCH_OMAP24XX +u32 non_wakeup_gpios; +u32 enabled_non_wakeup_gpios; + +u32 saved_datain; +u32 saved_fallingdetect; +u32 saved_risingdetect; +#endif spinlock_t lock; };
@@ -398,8 +408,10 @@ do { \__raw_writel (l, base + reg); \ } while(0) -static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int trigger) +#ifdef CONFIG_ARCH_OMAP24XX +static inline void set_24xx_gpio_triggering (struct gpio_bank *bank,int gpio,int trigger) { +void __iomem *base = bank->base;u32 gpio_bit =1 << gpio; MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
@@ -410,9 +422,21 @@ static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int tr trigger & __IRQT_RISEDGE);MOD_REG_BIT (OMAP24XX_GPIO_FALLINGDETECT , gpio_bit, trigger & __IRQT_FALEDGE); +if (likely (!(bank->non_wakeup_gpios & gpio_bit))) { +if (trigger !=0 ) +__raw_writel (1 << gpio, bank->base +OMAP24XX_GPIO_SETWKUENA ); +else +__raw_writel (1 << gpio, bank->base +OMAP24XX_GPIO_CLEARWKUENA ); + }else { +if (trigger !=0 ) + bank->enabled_non_wakeup_gpios |= gpio_bit; +else + bank->enabled_non_wakeup_gpios &= ~gpio_bit; + }/* FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only level * triggering requested. */ } +#endif static int _set_gpio_triggering (struct gpio_bank *bank,int gpio,int trigger) {
@@ -440,6 +464,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)else goto bad;break ; +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 :if (gpio &0x08 ) reg +=OMAP1610_GPIO_EDGE_CTRL2 ;
@@ -455,7 +480,14 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) l |=2 << (gpio <<1 );if (trigger & __IRQT_FALEDGE) l |=1 << (gpio <<1 ); +if (trigger) +/* Enable wake-up during idle for dynamic tick */ +__raw_writel (1 << gpio, bank->base +OMAP1610_GPIO_SET_WAKEUPENA ); +else +__raw_writel (1 << gpio, bank->base +OMAP1610_GPIO_CLEAR_WAKEUPENA );break ; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730 : reg +=OMAP730_GPIO_INT_CONTROL ; l =__raw_readl (reg);
@@ -466,9 +498,12 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else goto bad;break ; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX : -set_24xx_gpio_triggering (reg, gpio, trigger); +set_24xx_gpio_triggering (bank, gpio, trigger);break ; +#endif default :BUG (); goto bad;
@@ -652,8 +687,8 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enastatic int _set_gpio_wakeup (struct gpio_bank *bank,int gpio,int enable) {switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 : -case METHOD_GPIO_24XX :spin_lock (&bank->lock);if (enable) bank->suspend_wakeup |= (1 << gpio);
@@ -661,6 +696,24 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) bank->suspend_wakeup &= ~(1 << gpio);spin_unlock (&bank->lock);return 0 ; +#endif +#ifdef CONFIG_ARCH_OMAP24XX +case METHOD_GPIO_24XX : +spin_lock (&bank->lock); +if (enable) { +if (bank->non_wakeup_gpios & (1 << gpio)) { +printk (KERN_ERR "Unable to enable wakeup on" +"non-wakeup GPIO%d\n" , + (bank - gpio_bank) *32 + gpio); +spin_unlock (&bank->lock); +return -EINVAL ; + } + bank->suspend_wakeup |= (1 << gpio); + }else + bank->suspend_wakeup &= ~(1 << gpio); +spin_unlock (&bank->lock); +return 0 ; +#endif default :printk (KERN_ERR "Can't enable GPIO wakeup for method %i\n" , bank->method);
@@ -722,20 +775,6 @@ int omap_request_gpio(int gpio) __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); }#endif -#ifdef CONFIG_ARCH_OMAP16XX -if (bank->method ==METHOD_GPIO_1610 ) { -/* Enable wake-up during idle for dynamic tick */ -void __iomem *reg = bank->base +OMAP1610_GPIO_SET_WAKEUPENA ; -__raw_writel (1 <<get_gpio_index (gpio), reg); - } -#endif -#ifdef CONFIG_ARCH_OMAP24XX -if (bank->method ==METHOD_GPIO_24XX ) { -/* Enable wake-up during idle for dynamic tick */ -void __iomem *reg = bank->base +OMAP24XX_GPIO_SETWKUENA ; -__raw_writel (1 <<get_gpio_index (gpio), reg); - } -#endif spin_unlock (&bank->lock);return 0 ;
@@ -1081,13 +1120,18 @@ static int __init _omap_gpio_init(void)#endif #ifdef CONFIG_ARCH_OMAP24XX if (bank->method ==METHOD_GPIO_24XX ) { +static const u32 non_wakeup_gpios[] = { +0xe203ffc0 ,0x08700040 + }; +__raw_writel (0x00000000 , bank->base +OMAP24XX_GPIO_IRQENABLE1 );__raw_writel (0xffffffff , bank->base +OMAP24XX_GPIO_IRQSTATUS1 );__raw_writew (0x0015 , bank->base +OMAP24XX_GPIO_SYSCONFIG );/* Initialize interface clock ungated, module enabled */ __raw_writel (0 , bank->base +OMAP24XX_GPIO_CTRL ); - +if (i <ARRAY_SIZE (non_wakeup_gpios)) + bank->non_wakeup_gpios = non_wakeup_gpios[i]; gpio_count =32 ; }#endif
@@ -1201,6 +1245,80 @@ static struct sys_device omap_gpio_device = { .id = 0, .cls = &omap_gpio_sysclass, }; + +#endif + +#ifdef CONFIG_ARCH_OMAP24XX + +static int workaround_enabled; + +void omap2_gpio_prepare_for_retention (void ) +{ +int i, c =0 ; + +/* Remove triggering for all non-wakeup GPIOs. Otherwise spurious +* IRQs will be generated. See OMAP2420 Errata item 1.101. */ +for (i =0 ; i < gpio_bank_count; i++) { +struct gpio_bank *bank = &gpio_bank[i]; +u32 l1, l2; + +if (!(bank->enabled_non_wakeup_gpios)) +continue ; + bank->saved_datain =__raw_readl (bank->base +OMAP24XX_GPIO_DATAIN ); + l1 =__raw_readl (bank->base +OMAP24XX_GPIO_FALLINGDETECT ); + l2 =__raw_readl (bank->base +OMAP24XX_GPIO_RISINGDETECT ); + bank->saved_fallingdetect = l1; + bank->saved_risingdetect = l2; + l1 &= ~bank->enabled_non_wakeup_gpios; + l2 &= ~bank->enabled_non_wakeup_gpios; +__raw_writel (l1, bank->base +OMAP24XX_GPIO_FALLINGDETECT ); +__raw_writel (l2, bank->base +OMAP24XX_GPIO_RISINGDETECT ); + c++; + } +if (!c) { + workaround_enabled =0 ; +return ; + } + workaround_enabled =1 ; +} + +void omap2_gpio_resume_after_retention (void ) +{ +int i; + +if (!workaround_enabled) +return ; +for (i =0 ; i < gpio_bank_count; i++) { +struct gpio_bank *bank = &gpio_bank[i]; +u32 l; + +if (!(bank->enabled_non_wakeup_gpios)) +continue ; +__raw_writel (bank->saved_fallingdetect, + bank->base +OMAP24XX_GPIO_FALLINGDETECT ); +__raw_writel (bank->saved_risingdetect, + bank->base +OMAP24XX_GPIO_RISINGDETECT ); +/* Check if any of the non-wakeup interrupt GPIOs have changed +* state. If so, generate an IRQ by software. This is +* horribly racy, but it's the best we can do to work around +* this silicon bug. */ + l =__raw_readl (bank->base +OMAP24XX_GPIO_DATAIN ); + l ^= bank->saved_datain; + l &= bank->non_wakeup_gpios; +if (l) { +u32 old0, old1; + + old0 =__raw_readl (bank->base +OMAP24XX_GPIO_LEVELDETECT0 ); + old1 =__raw_readl (bank->base +OMAP24XX_GPIO_LEVELDETECT1 ); +__raw_writel (old0 | l, bank->base +OMAP24XX_GPIO_LEVELDETECT0 ); +__raw_writel (old1 | l, bank->base +OMAP24XX_GPIO_LEVELDETECT1 ); +__raw_writel (old0, bank->base +OMAP24XX_GPIO_LEVELDETECT0 ); +__raw_writel (old1, bank->base +OMAP24XX_GPIO_LEVELDETECT1 ); + } + } + +} +#endif /*
Signature · 1 line
1.4.4.2
Tony Lindgren
reviewerPATCH 3/10 ARM: OMAP: /sys/kernel/debug/omap_gpio
From: David Brownell <[email protected]>
Add some GPIO debug support: /sys/kernel/debug/omap_gpio dumps the state of all GPIOs that have been claimed, including basic IRQ info if relevant. Tested on 24xx, 16xx.
Includes minor bugfixes: recording IRQ trigger mode (this should probably be a genirq patch), adding missing space to non-wakeup warning
--- arch/arm/plat-omap/gpio.c | 130 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 129 insertions(+), 1 deletions(-)
arch/arm/plat-omap/gpio.c +129 -1
@@ -536,6 +536,10 @@ static int gpio_irq_type(unsigned irq, unsigned type) bank =get_gpio_bank (gpio);spin_lock (&bank->lock); retval =_set_gpio_triggering (bank,get_gpio_index (gpio), type); +if (retval ==0 ) { + irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK ; + irq_desc[irq].status |= type; + }spin_unlock (&bank->lock);return retval; }
@@ -702,7 +706,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)spin_lock (&bank->lock);if (enable) {if (bank->non_wakeup_gpios & (1 << gpio)) { -printk (KERN_ERR "Unable to enable wakeup on" +printk (KERN_ERR "Unable to enable wakeup on " "non-wakeup GPIO%d\n" , (bank - gpio_bank) *32 + gpio);spin_unlock (&bank->lock);
@@ -1360,3 +1364,127 @@ EXPORT_SYMBOL(omap_set_gpio_dataout);EXPORT_SYMBOL (omap_get_gpio_datain);arch_initcall (omap_gpio_sysinit); + + +#ifdef CONFIG_DEBUG_FS + +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +static int gpio_is_input (struct gpio_bank *bank,int mask) +{ +void __iomem *reg = bank->base; + +switch (bank->method) { +case METHOD_MPUIO : + reg +=OMAP_MPUIO_IO_CNTL ; +break ; +case METHOD_GPIO_1510 : + reg +=OMAP1510_GPIO_DIR_CONTROL ; +break ; +case METHOD_GPIO_1610 : + reg +=OMAP1610_GPIO_DIRECTION ; +break ; +case METHOD_GPIO_730 : + reg +=OMAP730_GPIO_DIR_CONTROL ; +break ; +case METHOD_GPIO_24XX : + reg +=OMAP24XX_GPIO_OE ; +break ; + } +return __raw_readl (reg) & mask; +} + + +static int dbg_gpio_show (struct seq_file *s,void *unused) +{ +unsigned i, j, gpio; + +for (i =0 , gpio =0 ; i < gpio_bank_count; i++) { +struct gpio_bank *bank = gpio_bank + i; +unsigned bankwidth =16 ; +u32 mask =1 ; + +if (!cpu_is_omap24xx () && bank->method ==METHOD_MPUIO ) + gpio =OMAP_MPUIO (0 ); +else if (cpu_is_omap24xx () ||cpu_is_omap730 ()) + bankwidth =32 ; + +for (j =0 ; j < bankwidth; j++, gpio++, mask <<=1 ) { +unsigned irq, value, is_in, irqstat; + +if (!(bank->reserved_map & mask)) +continue ; + + irq = bank->virtual_irq_start + j; + value =omap_get_gpio_datain (gpio); + is_in =gpio_is_input (bank, mask); + +if (!cpu_is_omap24xx () && bank->method ==METHOD_MPUIO ) +seq_printf (s,"MPUIO %2d: " , j); +else +seq_printf (s,"GPIO %3d: " , gpio); +seq_printf (s,"%s %s" , + is_in ?"in " :"out" , + value ?"hi" :"lo" ); + + irqstat = irq_desc[irq].status; +if (is_in && ((bank->suspend_wakeup & mask) + || irqstat &IRQ_TYPE_SENSE_MASK )) { +char *trigger =NULL ; + +switch (irqstat &IRQ_TYPE_SENSE_MASK ) { +case IRQ_TYPE_EDGE_FALLING : + trigger ="falling" ; +break ; +case IRQ_TYPE_EDGE_RISING : + trigger ="rising" ; +break ; +case IRQ_TYPE_EDGE_BOTH : + trigger ="bothedge" ; +break ; +case IRQ_TYPE_LEVEL_LOW : + trigger ="low" ; +break ; +case IRQ_TYPE_LEVEL_HIGH : + trigger ="high" ; +break ; +case IRQ_TYPE_NONE : + trigger ="(unspecified)" ; +break ; + } +seq_printf (s,", irq-%d %s%s" , + irq, trigger, + (bank->suspend_wakeup & mask) + ?" wakeup" :"" ); + } +seq_printf (s,"\n" ); + } + +if (!cpu_is_omap24xx () && bank->method ==METHOD_MPUIO ) { +seq_printf (s,"\n" ); + gpio =0 ; + } + } +return 0 ; +} + +static int dbg_gpio_open (struct inode *inode,struct file *file) +{ +return single_open (file, dbg_gpio_show, inode->u.generic_ip/*i_private*/ ); +} + +static const struct file_operations debug_fops = { + .open = dbg_gpio_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init omap_gpio_debuginit (void ) +{ + (void )debugfs_create_file ("omap_gpio" ,S_IRUGO ,NULL ,NULL , &debug_fops); +return 0 ; +} +late_initcall (omap_gpio_debuginit); +#endif
Signature · 1 line
1.4.4.2
Tony Lindgren
reviewerPATCH 4/10 ARM: OMAP: gpio init section cleanups
From: David Brownell <[email protected]>
Minor GPIO cleanups: remove needless #include, and omap_gpio_init() should be __init, as well as all the board init code calling it.
--- arch/arm/mach-omap1/board-fsample.c | 2 +- arch/arm/mach-omap1/board-h3.c | 2 +- arch/arm/mach-omap1/board-innovator.c | 2 +- arch/arm/mach-omap1/board-perseus2.c | 2 +- arch/arm/plat-omap/gpio.c | 3 +-- 5 files changed, 5 insertions(+), 6 deletions(-)
arch/arm/mach-omap1/board-fsample.c +1 -1
@@ -246,7 +246,7 @@ static void __init fsample_init_smc91x(void)mdelay (50 ); } -void omap_fsample_init_irq (void ) +static void __init omap_fsample_init_irq (void ) {omap1_init_common_hw ();omap_init_irq ();
arch/arm/mach-omap1/board-h3.c +1 -1
@@ -455,7 +455,7 @@ static void __init h3_init_smc91x(void) } } -void h3_init_irq (void ) +static void __init h3_init_irq (void ) {omap1_init_common_hw ();omap_init_irq ();
arch/arm/mach-omap1/board-innovator.c +1 -1
@@ -308,7 +308,7 @@ static void __init innovator_init_smc91x(void) } } -void innovator_init_irq (void ) +static void __init innovator_init_irq (void ) {omap1_init_common_hw ();omap_init_irq ();
arch/arm/mach-omap1/board-perseus2.c +1 -1
@@ -246,7 +246,7 @@ static void __init perseus2_init_smc91x(void)mdelay (50 ); } -void omap_perseus2_init_irq (void ) +static void __init omap_perseus2_init_irq (void ) {omap1_init_common_hw ();omap_init_irq ();
arch/arm/plat-omap/gpio.c +1 -2
@@ -13,7 +13,6 @@#include <linux/init.h> #include <linux/module.h> -#include <linux/sched.h> #include <linux/interrupt.h> #include <linux/ptrace.h> #include <linux/sysdev.h>
@@ -1329,7 +1328,7 @@ void omap2_gpio_resume_after_retention(void)* This may get called early from board specific init * for boards that have interrupts routed via FPGA. */ -int omap_gpio_init (void ) +int __init omap_gpio_init (void ) {if (!initialized)return _omap_gpio_init ();
Signature · 1 line
1.4.4.2
Tony Lindgren
reviewerPATCH 5/10 ARM: OMAP: gpio object shrinkage, cleanup
From: David Brownell <[email protected]>
More GPIO/IRQ cleanup:
- compile-time removal of much useless code
* mpuio support on non-OMAP1.
* 15xx/730/24xx gpio support on 1610
* 15xx/730/16xx gpio support on 24xx
* etc
- remove all BUG() calls, which are always bad news ... replaced some with normal fault reports for that call, others with WARN_ON(1).
- small mpuio bugfix: add missing set_type() method
Oh, and fix a minor merge issue: inode->u.generic_ip is now gone.
--- arch/arm/plat-omap/gpio.c | 166 +++++++++++++++++++++++++++++++++++---------- 1 files changed, 130 insertions(+), 36 deletions(-)
arch/arm/plat-omap/gpio.c +130 -36
@@ -267,21 +267,34 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)u32 l;switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO : reg +=OMAP_MPUIO_IO_CNTL ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510 : reg +=OMAP1510_GPIO_DIR_CONTROL ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 : reg +=OMAP1610_GPIO_DIRECTION ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730 : reg +=OMAP730_GPIO_DIR_CONTROL ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX : reg +=OMAP24XX_GPIO_OE ;break ; +#endif +default : +WARN_ON (1 ); +return ; } l =__raw_readl (reg);if (is_input)
@@ -309,6 +322,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)u32 l =0 ;switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO : reg +=OMAP_MPUIO_OUTPUT ; l =__raw_readl (reg);
@@ -317,6 +331,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) else l &= ~(1 << gpio);break ; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510 : reg +=OMAP1510_GPIO_DATA_OUTPUT ; l =__raw_readl (reg);
@@ -325,6 +341,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) else l &= ~(1 << gpio);break ; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 :if (enable) reg +=OMAP1610_GPIO_SET_DATAOUT ;
@@ -332,6 +350,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) reg +=OMAP1610_GPIO_CLEAR_DATAOUT ; l =1 << gpio;break ; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730 : reg +=OMAP730_GPIO_DATA_OUTPUT ; l =__raw_readl (reg);
@@ -340,6 +360,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) else l &= ~(1 << gpio);break ; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX :if (enable) reg +=OMAP24XX_GPIO_SETDATAOUT ;
@@ -347,8 +369,9 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) reg +=OMAP24XX_GPIO_CLEARDATAOUT ; l =1 << gpio;break ; +#endif default : -BUG (); +WARN_ON (1 );return ; }__raw_writel (l, reg);
@@ -372,28 +395,37 @@ int omap_get_gpio_datain(int gpio)void __iomem *reg;if (check_gpio (gpio) <0 ) -return -1 ; +return -EINVAL ; bank =get_gpio_bank (gpio); reg = bank->base;switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO : reg +=OMAP_MPUIO_INPUT_LATCH ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510 : reg +=OMAP1510_GPIO_DATA_INPUT ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 : reg +=OMAP1610_GPIO_DATAIN ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730 : reg +=OMAP730_GPIO_DATA_INPUT ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX : reg +=OMAP24XX_GPIO_DATAIN ;break ; +#endif default : -BUG (); -return -1 ; +return -EINVAL ; }return (__raw_readl (reg) & (1 <<get_gpio_index (gpio))) !=0 ;
@@ -443,6 +475,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)u32 l =0 ;switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO : reg +=OMAP_MPUIO_GPIO_INT_EDGE ; l =__raw_readl (reg);
@@ -453,6 +486,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else goto bad;break ; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510 : reg +=OMAP1510_GPIO_INT_CONTROL ; l =__raw_readl (reg);
@@ -463,6 +498,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else goto bad;break ; +#endif #ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 :if (gpio &0x08 )
@@ -470,9 +506,6 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)else reg +=OMAP1610_GPIO_EDGE_CTRL1 ; gpio &=0x07 ; -/* We allow only edge triggering, i.e. two lowest bits */ -if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL)) -BUG (); l =__raw_readl (reg); l &= ~(3 << (gpio <<1 ));if (trigger & __IRQT_RISEDGE)
@@ -504,7 +537,6 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)break ;#endif default : -BUG (); goto bad; }__raw_writel (l, reg);
@@ -519,7 +551,7 @@ static int gpio_irq_type(unsigned irq, unsigned type)unsigned gpio;int retval; -if (irq >IH_MPUIO_BASE ) +if (!cpu_is_omap24xx () && irq >IH_MPUIO_BASE ) gpio =OMAP_MPUIO (irq -IH_MPUIO_BASE );else gpio = irq -IH_GPIO_BASE ;
@@ -527,9 +559,12 @@ static int gpio_irq_type(unsigned irq, unsigned type)if (check_gpio (gpio) <0 )return -EINVAL ; -if (type &IRQT_PROBE ) +if (type & ~IRQ_TYPE_SENSE_MASK )return -EINVAL ; -if (!cpu_is_omap24xx () && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL))) + +/* OMAP1 allows only only edge triggering */ +if (!cpu_is_omap24xx () + && (type & (IRQ_TYPE_LEVEL_LOW |IRQ_TYPE_LEVEL_HIGH )))return -EINVAL ; bank =get_gpio_bank (gpio);
@@ -548,24 +583,34 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)void __iomem *reg = bank->base;switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO :/* MPUIO irqstatus is reset by reading the status register, * so do nothing here */ return ; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510 : reg +=OMAP1510_GPIO_INT_STATUS ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 : reg +=OMAP1610_GPIO_IRQSTATUS1 ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730 : reg +=OMAP730_GPIO_INT_STATUS ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX : reg +=OMAP24XX_GPIO_IRQSTATUS1 ;break ; +#endif default : -BUG (); +WARN_ON (1 );return ; }__raw_writel (gpio_mask, reg);
@@ -588,31 +633,41 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)u32 mask;switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO : reg +=OMAP_MPUIO_GPIO_MASKIT ; mask =0xffff ; inv =1 ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510 : reg +=OMAP1510_GPIO_INT_MASK ; mask =0xffff ; inv =1 ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 : reg +=OMAP1610_GPIO_IRQENABLE1 ; mask =0xffff ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730 : reg +=OMAP730_GPIO_INT_MASK ; mask =0xffffffff ; inv =1 ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX : reg +=OMAP24XX_GPIO_IRQENABLE1 ; mask =0xffffffff ;break ; +#endif default : -BUG (); +WARN_ON (1 );return 0 ; }
@@ -629,6 +684,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enabu32 l;switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO : reg +=OMAP_MPUIO_GPIO_MASKIT ; l =__raw_readl (reg);
@@ -637,6 +693,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab else l |= gpio_mask;break ; +#endif +#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510 : reg +=OMAP1510_GPIO_INT_MASK ; l =__raw_readl (reg);
@@ -645,6 +703,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab else l |= gpio_mask;break ; +#endif +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 :if (enable) reg +=OMAP1610_GPIO_SET_IRQENABLE1 ;
@@ -652,6 +712,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab reg +=OMAP1610_GPIO_CLEAR_IRQENABLE1 ; l = gpio_mask;break ; +#endif +#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730 : reg +=OMAP730_GPIO_INT_MASK ; l =__raw_readl (reg);
@@ -660,6 +722,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab else l |= gpio_mask;break ; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX :if (enable) reg +=OMAP24XX_GPIO_SETIRQENABLE1 ;
@@ -667,8 +731,9 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab reg +=OMAP24XX_GPIO_CLEARIRQENABLE1 ; l = gpio_mask;break ; +#endif default : -BUG (); +WARN_ON (1 );return ; }__raw_writel (l, reg);
@@ -837,8 +902,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) desc->chip->ack (irq); bank =get_irq_data (irq); +#ifdef CONFIG_ARCH_OMAP1 if (bank->method ==METHOD_MPUIO ) isr_reg = bank->base +OMAP_MPUIO_GPIO_INT ; +#endif #ifdef CONFIG_ARCH_OMAP15XX if (bank->method ==METHOD_GPIO_1510 ) isr_reg = bank->base +OMAP1510_GPIO_INT_STATUS ;
@@ -984,6 +1051,22 @@ static void gpio_unmask_irq(unsigned int irq)_set_gpio_irqenable (bank, gpio_idx,1 ); } +static struct irq_chip gpio_irq_chip = { + .name ="GPIO" , + .shutdown = gpio_irq_shutdown, + .ack = gpio_ack_irq, + .mask = gpio_mask_irq, + .unmask = gpio_unmask_irq, + .set_type = gpio_irq_type, + .set_wake = gpio_wake_enable, +}; + +/*---------------------------------------------------------------------*/ + +#ifdef CONFIG_ARCH_OMAP1 + +/* MPUIO uses the always-on 32k clock */ +static void mpuio_ack_irq (unsigned int irq) {/* The ISR is reset automatically, so do nothing here. */
@@ -1005,23 +1088,26 @@ static void mpuio_unmask_irq(unsigned int irq) _set_gpio_irqenable(bank, gpio, 1); } -static struct irq_chip gpio_irq_chip = { - .name ="GPIO" , - .shutdown = gpio_irq_shutdown, - .ack = gpio_ack_irq, - .mask = gpio_mask_irq, - .unmask = gpio_unmask_irq, +static struct irq_chip mpuio_irq_chip = { + .name ="MPUIO" , + .ack = mpuio_ack_irq, + .mask = mpuio_mask_irq, + .unmask = mpuio_unmask_irq, .set_type = gpio_irq_type, - .set_wake = gpio_wake_enable, }; -static struct irq_chip mpuio_irq_chip = { - .name ="MPUIO" , - .ack = mpuio_ack_irq, - .mask = mpuio_mask_irq, - .unmask = mpuio_unmask_irq, - .set_type = gpio_irq_type, -}; + +#define bank_is_mpuio (bank) ((bank)->method == METHOD_MPUIO) + +#else + +extern struct irq_chip mpuio_irq_chip; + +#define bank_is_mpuio (bank) 0 + +#endif + +/*---------------------------------------------------------------------*/ static int initialized;static struct clk * gpio_ick;
@@ -1097,9 +1183,8 @@ static int __init _omap_gpio_init(void) bank->reserved_map =0 ; bank->base =IO_ADDRESS (bank->base);spin_lock_init (&bank->lock); -if (bank->method ==METHOD_MPUIO ) { +if (bank_is_mpuio (bank))omap_writew (0xFFFF ,OMAP_MPUIO_BASE +OMAP_MPUIO_GPIO_MASKIT ); - }#ifdef CONFIG_ARCH_OMAP15XX if (bank->method ==METHOD_GPIO_1510 ) {__raw_writew (0xffff , bank->base +OMAP1510_GPIO_INT_MASK );
@@ -1140,7 +1225,7 @@ static int __init _omap_gpio_init(void)#endif for (j = bank->virtual_irq_start; j < bank->virtual_irq_start + gpio_count; j++) { -if (bank->method ==METHOD_MPUIO ) +if (bank_is_mpuio (bank))set_irq_chip (j, &mpuio_irq_chip);else set_irq_chip (j, &gpio_irq_chip);
@@ -1180,16 +1265,20 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)void __iomem *wake_set;switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 : wake_status = bank->base +OMAP1610_GPIO_WAKEUPENABLE ; wake_clear = bank->base +OMAP1610_GPIO_CLEAR_WAKEUPENA ; wake_set = bank->base +OMAP1610_GPIO_SET_WAKEUPENA ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX : wake_status = bank->base +OMAP24XX_GPIO_SETWKUENA ; wake_clear = bank->base +OMAP24XX_GPIO_CLEARWKUENA ; wake_set = bank->base +OMAP24XX_GPIO_SETWKUENA ;break ; +#endif default :continue ; }
@@ -1217,14 +1306,18 @@ static int omap_gpio_resume(struct sys_device *dev)void __iomem *wake_set;switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610 : wake_clear = bank->base +OMAP1610_GPIO_CLEAR_WAKEUPENA ; wake_set = bank->base +OMAP1610_GPIO_SET_WAKEUPENA ;break ; +#endif +#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX : wake_clear = bank->base +OMAP24XX_GPIO_CLEARWKUENA ; wake_set = bank->base +OMAP24XX_GPIO_SETWKUENA ;break ; +#endif default :continue ; }
@@ -1404,7 +1497,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)unsigned bankwidth =16 ;u32 mask =1 ; -if (!cpu_is_omap24xx () && bank->method ==METHOD_MPUIO ) +if (bank_is_mpuio (bank)) gpio =OMAP_MPUIO (0 );else if (cpu_is_omap24xx () ||cpu_is_omap730 ()) bankwidth =32 ;
@@ -1419,7 +1512,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) value =omap_get_gpio_datain (gpio); is_in =gpio_is_input (bank, mask); -if (!cpu_is_omap24xx () && bank->method ==METHOD_MPUIO ) +if (bank_is_mpuio (bank))seq_printf (s,"MPUIO %2d: " , j);else seq_printf (s,"GPIO %3d: " , gpio);
@@ -1460,7 +1553,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)seq_printf (s,"\n" ); } -if (!cpu_is_omap24xx () && bank->method ==METHOD_MPUIO ) { +if (bank_is_mpuio (bank)) {seq_printf (s,"\n" ); gpio =0 ; }
@@ -1470,7 +1563,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)static int dbg_gpio_open (struct inode *inode,struct file *file) { -return single_open (file, dbg_gpio_show, inode->u.generic_ip/*i_private*/ ); +return single_open (file, dbg_gpio_show, &inode->i_private); }static const struct file_operations debug_fops = {
@@ -1482,7 +1575,8 @@ static const struct file_operations debug_fops = {static int __init omap_gpio_debuginit (void ) { - (void )debugfs_create_file ("omap_gpio" ,S_IRUGO ,NULL ,NULL , &debug_fops); + (void )debugfs_create_file ("omap_gpio" ,S_IRUGO , +NULL ,NULL , &debug_fops);return 0 ; }late_initcall (omap_gpio_debuginit);
Signature · 1 line
1.4.4.2
Tony Lindgren
reviewerPATCH 6/10 ARM: OMAP: plat-omap changes for 2430 SDP
From: Syed Mohammed Khasim <[email protected]>
This patch adds minimal OMAP2430 support to plat-omap files to get the kernel booting on 2430SDP.
--- arch/arm/plat-omap/devices.c | 6 +++- arch/arm/plat-omap/dmtimer.c | 2 + arch/arm/plat-omap/gpio.c | 76 ++++++++++++++++++++++++++++++++++------- arch/arm/plat-omap/mcbsp.c | 15 +++++--- 4 files changed, 80 insertions(+), 19 deletions(-)
arch/arm/plat-omap/devices.c +5 -1
@@ -429,6 +429,10 @@ static inline void omap_init_rng(void) {}*/ static int __init omap_init_devices (void ) { +/* +* Need to enable relevant once for 2430 SDP +*/ +#ifndef CONFIG_MACH_OMAP_2430SDP /* please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */
@@ -438,7 +442,7 @@ static int __init omap_init_devices(void)omap_init_uwire ();omap_init_wdt ();omap_init_rng (); - +#endif return 0 ; }arch_initcall (omap_init_devices);
arch/arm/plat-omap/dmtimer.c +2 -0
@@ -506,6 +506,8 @@ int omap_dm_timer_init(void) BUG_ON(dm_source_clocks[i] == NULL); }#endif +if (cpu_is_omap243x ()) + dm_timers[0 ].phys_base =0x49018000 ;for (i =0 ; i < dm_timer_count; i++) {#ifdef CONFIG_ARCH_OMAP2
arch/arm/plat-omap/gpio.c +63 -13
112 lines not on this page · raw message
arch/arm/plat-omap/mcbsp.c +10 -5
@@ -225,11 +225,16 @@ static void omap_mcbsp_dsp_free(void)#ifdef CONFIG_ARCH_OMAP2 static void omap2_mcbsp2_mux_setup (void ) { -omap_cfg_reg (Y15_24XX_MCBSP2_CLKX ); -omap_cfg_reg (R14_24XX_MCBSP2_FSX ); -omap_cfg_reg (W15_24XX_MCBSP2_DR ); -omap_cfg_reg (V15_24XX_MCBSP2_DX ); -omap_cfg_reg (V14_24XX_GPIO117 ); +if (cpu_is_omap2420 ()) { +omap_cfg_reg (Y15_24XX_MCBSP2_CLKX ); +omap_cfg_reg (R14_24XX_MCBSP2_FSX ); +omap_cfg_reg (W15_24XX_MCBSP2_DR ); +omap_cfg_reg (V15_24XX_MCBSP2_DX ); +omap_cfg_reg (V14_24XX_GPIO117 ); + } +/* +* Need to add MUX settings for OMAP 2430 SDP +*/ }#endif
Signature · 1 line
1.4.4.2
Tony Lindgren
reviewerPATCH 7/10 ARM: OMAP: speed up gpio irq handling
From: David Brownell <[email protected]>
Speedup and shrink GPIO irq handling code, by using a pointer that's available in the irq_chip structure instead of calling the get_gpio_bank() function. On OMAP1 this saves 44 words, most of which were in IRQ critical path methods. Hey, every few instructions help.
--- arch/arm/plat-omap/gpio.c | 17 +++++++++-------- 1 files changed, 9 insertions(+), 8 deletions(-)
arch/arm/plat-omap/gpio.c +9 -8
@@ -584,7 +584,7 @@ static int gpio_irq_type(unsigned irq, unsigned type) && (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))return -EINVAL ; - bank =get_gpio_bank (gpio); + bank =get_irq_chip_data (irq);spin_lock (&bank->lock); retval =_set_gpio_triggering (bank,get_gpio_index (gpio), type);if (retval ==0 ) {
@@ -823,7 +823,7 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable)if (check_gpio (gpio) <0 )return -ENODEV ; - bank =get_gpio_bank (gpio); + bank =get_irq_chip_data (irq); retval =_set_gpio_wakeup (bank,get_gpio_index (gpio), enable);return retval;
@@ -1038,7 +1038,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)static void gpio_irq_shutdown (unsigned int irq) {unsigned int gpio = irq -IH_GPIO_BASE ; -struct gpio_bank *bank =get_gpio_bank (gpio); +struct gpio_bank *bank =get_irq_chip_data (irq);_reset_gpio (bank, gpio); }
@@ -1046,7 +1046,7 @@ static void gpio_irq_shutdown(unsigned int irq)static void gpio_ack_irq (unsigned int irq) {unsigned int gpio = irq -IH_GPIO_BASE ; -struct gpio_bank *bank =get_gpio_bank (gpio); +struct gpio_bank *bank =get_irq_chip_data (irq);_clear_gpio_irqstatus (bank, gpio); }
@@ -1054,7 +1054,7 @@ static void gpio_ack_irq(unsigned int irq)static void gpio_mask_irq (unsigned int irq) {unsigned int gpio = irq -IH_GPIO_BASE ; -struct gpio_bank *bank =get_gpio_bank (gpio); +struct gpio_bank *bank =get_irq_chip_data (irq);_set_gpio_irqenable (bank, gpio,0 ); }
@@ -1063,7 +1063,7 @@ static void gpio_unmask_irq(unsigned int irq) {unsigned int gpio = irq -IH_GPIO_BASE ;unsigned int gpio_idx =get_gpio_index (gpio); -struct gpio_bank *bank =get_gpio_bank (gpio); +struct gpio_bank *bank =get_irq_chip_data (irq);_set_gpio_irqenable (bank, gpio_idx,1 ); }
@@ -1092,7 +1092,7 @@ static void mpuio_ack_irq(unsigned int irq)static void mpuio_mask_irq (unsigned int irq) {unsigned int gpio =OMAP_MPUIO (irq -IH_MPUIO_BASE ); -struct gpio_bank *bank =get_gpio_bank (gpio); +struct gpio_bank *bank =get_irq_chip_data (irq);_set_gpio_irqenable (bank, gpio,0 ); }
@@ -1100,7 +1100,7 @@ static void mpuio_mask_irq(unsigned int irq)static void mpuio_unmask_irq (unsigned int irq) {unsigned int gpio =OMAP_MPUIO (irq -IH_MPUIO_BASE ); -struct gpio_bank *bank =get_gpio_bank (gpio); +struct gpio_bank *bank =get_irq_chip_data (irq);_set_gpio_irqenable (bank, gpio,1 ); }
@@ -1275,6 +1275,7 @@ static int __init _omap_gpio_init(void)#endif for (j = bank->virtual_irq_start; j < bank->virtual_irq_start + gpio_count; j++) { +set_irq_chip_data (j, bank);if (bank_is_mpuio (bank))set_irq_chip (j, &mpuio_irq_chip);else
Signature · 1 line
1.4.4.2
Tony Lindgren
reviewerPATCH 8/10 ARM: OMAP: MPUIO wake updates
From: David Brownell <[email protected]>
GPIO and MPUIO wake updates:
- Hook MPUIOs into the irq wakeup framework too. This uses a platform device to update irq enables during system sleep states, instead of a sys_device, since the latter is no longer needed for such things.
- Also forward enable/disable irq wake requests to the relevant GPIO controller, so the top level IRQ dispatcher can (eventually) handle these wakeup events automatically if more than one GPIO pin needs to be a wakeup event source.
- Minor tweak to the 24xx non-wakeup gpio stuff: no need to check such read-only data under the spinlock.
This assumes (maybe wrongly?) that only 16xx can do GPIO wakeup; without a 15xx I can't test such stuff.
Also this expects the top level IRQ dispatcher to properly handle requests to enable/disable irq wake, which is currently known to be wrong: omap1 saves the flags but ignores them, omap2 doesn't even save it. (Wakeup events are, wrongly, hardwired in the relevant mach-omapX/pm.c file ...) So MPUIO irqs won't yet trigger system wakeup.
--- arch/arm/plat-omap/gpio.c | 93 ++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 83 insertions(+), 10 deletions(-)
arch/arm/plat-omap/gpio.c +83 -10
@@ -773,29 +773,35 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) {switch (bank->method) {#ifdef CONFIG_ARCH_OMAP16XX +case METHOD_MPUIO :case METHOD_GPIO_1610 :spin_lock (&bank->lock); -if (enable) +if (enable) { bank->suspend_wakeup |= (1 << gpio); -else +enable_irq_wake (bank->irq); + }else { +disable_irq_wake (bank->irq); bank->suspend_wakeup &= ~(1 << gpio); + }spin_unlock (&bank->lock);return 0 ;#endif #ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX : +if (bank->non_wakeup_gpios & (1 << gpio)) { +printk (KERN_ERR "Unable to modify wakeup on " +"non-wakeup GPIO%d\n" , + (bank - gpio_bank) *32 + gpio); +return -EINVAL ; + }spin_lock (&bank->lock);if (enable) { -if (bank->non_wakeup_gpios & (1 << gpio)) { -printk (KERN_ERR "Unable to enable wakeup on " -"non-wakeup GPIO%d\n" , - (bank - gpio_bank) *32 + gpio); -spin_unlock (&bank->lock); -return -EINVAL ; - } bank->suspend_wakeup |= (1 << gpio); - }else +enable_irq_wake (bank->irq); + }else { +disable_irq_wake (bank->irq); bank->suspend_wakeup &= ~(1 << gpio); + }spin_unlock (&bank->lock);return 0 ;#endif
@@ -1111,16 +1117,81 @@ static struct irq_chip mpuio_irq_chip = { .mask = mpuio_mask_irq, .unmask = mpuio_unmask_irq, .set_type = gpio_irq_type, +#ifdef CONFIG_ARCH_OMAP16XX + /* REVISIT: assuming only 16xx supports MPUIO wake events */ + .set_wake = gpio_wake_enable, +#endif };#define bank_is_mpuio (bank) ((bank)->method == METHOD_MPUIO) + +#ifdef CONFIG_ARCH_OMAP16XX + +#include <linux/platform_device.h> + +static int omap_mpuio_suspend_late (struct platform_device *pdev,pm_message_t mesg) +{ +struct gpio_bank *bank =platform_get_drvdata (pdev); +void __iomem *mask_reg = bank->base +OMAP_MPUIO_GPIO_MASKIT ; + +spin_lock (&bank->lock); + bank->saved_wakeup =__raw_readl (mask_reg); +__raw_writel (0xffff & ~bank->suspend_wakeup, mask_reg); +spin_unlock (&bank->lock); + +return 0 ; +} + +static int omap_mpuio_resume_early (struct platform_device *pdev) +{ +struct gpio_bank *bank =platform_get_drvdata (pdev); +void __iomem *mask_reg = bank->base +OMAP_MPUIO_GPIO_MASKIT ; + +spin_lock (&bank->lock); +__raw_writel (bank->saved_wakeup, mask_reg); +spin_unlock (&bank->lock); + +return 0 ; +} + +/* use platform_driver for this, now that there's no longer any +* point to sys_device (other than not disturbing old code). +*/ +static struct platform_driver omap_mpuio_driver = { + .suspend_late = omap_mpuio_suspend_late, + .resume_early = omap_mpuio_resume_early, + .driver = { + .name ="mpuio" , + }, +}; + +static struct platform_device omap_mpuio_device = { + .name ="mpuio" , + .id =-1 , + .dev = { + .driver = &omap_mpuio_driver.driver, + } +/* could list the /proc/iomem resources */ +}; + +static inline void mpuio_init (void ) +{ +if (platform_driver_register (&omap_mpuio_driver) ==0 ) + (void )platform_device_register (&omap_mpuio_device); +} + +#else +static inline void mpuio_init (void ) {} +#endif /* 16xx */ +#else extern struct irq_chip mpuio_irq_chip;#define bank_is_mpuio (bank) 0 +static inline void mpuio_init (void ) {}#endif
@@ -1487,6 +1558,8 @@ static int __init omap_gpio_sysinit(void)if (!initialized) ret =_omap_gpio_init (); +mpuio_init (); +#if defined(CONFIG_ARCH_OMAP16XX ) || defined(CONFIG_ARCH_OMAP24XX )if (cpu_is_omap16xx () ||cpu_is_omap24xx ()) {if (ret ==0 ) {
Signature · 1 line
1.4.4.2
Tony Lindgren
reviewerPATCH 9/10 ARM: OMAP: fix OMAP1 mpuio suspend/resume oops
From: David Brownell <[email protected]>
Fix oops in omap16xx mpuio suspend/resume code; field wasn't initialized
--- arch/arm/plat-omap/gpio.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
arch/arm/plat-omap/gpio.c +2 -0
@@ -1178,6 +1178,8 @@ static struct platform_device omap_mpuio_device = {static inline void mpuio_init (void ) { +platform_set_drvdata (&omap_mpuio_device, &gpio_bank_1610[0 ]); +if (platform_driver_register (&omap_mpuio_driver) ==0 ) (void )platform_device_register (&omap_mpuio_device); }
Signature · 1 line
1.4.4.2
Re: [PATCH 4/10] ARM: OMAP: gpio init section cleanups
In reply to Tony LindgrenQuoted 7 lines · Tony Lindgren
From: David Brownell <[email protected]>
Minor GPIO cleanups: remove needless #include, and
omap_gpio_init()should be__init, as well as all the board init code calling it.Signed-off-by David Brownell <[email protected]>Signed-off-by Tony Lindgren <[email protected]>
I've applied 8 patches from this series by cherry picking it from your git tree, minus this patch which git wouldn't apply due to fuzz in arch/arm/plat-omap/gpio.c.
Quoted 79 lines
--- arch/arm/mach-omap1/board-fsample.c | 2 +- arch/arm/mach-omap1/board-h3.c | 2 +- arch/arm/mach-omap1/board-innovator.c | 2 +- arch/arm/mach-omap1/board-perseus2.c | 2 +- arch/arm/plat-omap/gpio.c | 3 +-- 5 files changed, 5 insertions(+), 6 deletions(-)arch/arm/mach-omap1/board-fsample.c +1
-1@@ -246,7 +246,7 @@ static void __init fsample_init_smc91x(void)mdelay (50 ); } -void omap_fsample_init_irq (void ) +static void __init omap_fsample_init_irq (void ) {omap1_init_common_hw ();omap_init_irq ();arch/arm/mach-omap1/board-h3.c +1
-1@@ -455,7 +455,7 @@ static void __init h3_init_smc91x(void) } } -void h3_init_irq (void ) +static void __init h3_init_irq (void ) {omap1_init_common_hw ();omap_init_irq ();arch/arm/mach-omap1/board-innovator.c +1
-1@@ -308,7 +308,7 @@ static void __init innovator_init_smc91x(void) } } -void innovator_init_irq (void ) +static void __init innovator_init_irq (void ) {omap1_init_common_hw ();omap_init_irq ();arch/arm/mach-omap1/board-perseus2.c +1
-1@@ -246,7 +246,7 @@ static void __init perseus2_init_smc91x(void)mdelay (50 ); } -void omap_perseus2_init_irq (void ) +static void __init omap_perseus2_init_irq (void ) {omap1_init_common_hw ();omap_init_irq ();arch/arm/plat-omap/gpio.c +1
-2@@ -13,7 +13,6 @@#include <linux/init.h> #include <linux/module.h> -#include <linux/sched.h> #include <linux/interrupt.h> #include <linux/ptrace.h> #include <linux/sysdev.h> @@ -1329,7 +1328,7 @@ void omap2_gpio_resume_after_retention(void)* This may get called early from board specific init * for boards that have interrupts routed via FPGA. */ -int omap_gpio_init (void ) +int __init omap_gpio_init (void ) {if (!initialized)return _omap_gpio_init ();Signature · 7 lines
1.4.4.2 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Signature · 3 lines
Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of:
Re: [PATCH 4/10] ARM: OMAP: gpio init section cleanups
Quoted 6 lines · Russell King
Quoted 5 lines · Tony Lindgren
From: David Brownell <[email protected]>
Minor GPIO cleanups: remove needless #include, and
omap_gpio_init()should be__init, as well as all the board init code calling it.
Quoted 6 lines
Quoted 2 lines
Signed-off-by David Brownell <[email protected]>Signed-off-by Tony Lindgren <[email protected]>I've applied 8 patches from this series by cherry picking it from your git tree, minus this patch which git wouldn't apply due to fuzz in
arch/arm/plat-omap/gpio.c.
Incidentally, when doing a build after these patches, I'm seeing:
arch/arm/plat-omap/dma.c: In function `omap_get_dma_src_pos':arch/arm/plat-omap/dma.c:750: warning: 'offset' might be used uninitialized in this function arch/arm/plat-omap/dma.c: In function `omap_get_dma_dst_pos':arch/arm/plat-omap/dma.c:772: warning: 'offset' might be used uninitialized in this function
These look like they're valid warnings to me.
Signature · 3 lines
Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of:
Tony Lindgren
reviewerRe: [PATCH 4/10] ARM: OMAP: gpio init section cleanups
Quoted 7 lines · Russell King
Quoted 6 lines · Russell King
Quoted 5 lines · Tony Lindgren
From: David Brownell <[email protected]>
Minor GPIO cleanups: remove needless #include, and
omap_gpio_init()should be__init, as well as all the board init code calling it.
Quoted 6 lines
Quoted 6 lines
Quoted 2 lines
Signed-off-by David Brownell <[email protected]>Signed-off-by Tony Lindgren <[email protected]>I've applied 8 patches from this series by cherry picking it from your git tree, minus this patch which git wouldn't apply due to fuzz in
arch/arm/plat-omap/gpio.c.
I wonder what causes the fuzz? Do you have your git tree somewhere so I can update this patch against it?
Quoted 8 lines
Incidentally, when doing a build after these patches, I'm seeing:
arch/arm/plat-omap/dma.c: In function `omap_get_dma_src_pos':arch/arm/plat-omap/dma.c:750: warning: 'offset' might be used uninitialized in this functionarch/arm/plat-omap/dma.c: In function `omap_get_dma_dst_pos':arch/arm/plat-omap/dma.c:772: warning: 'offset' might be used uninitialized in this functionThese look like they're valid warnings to me.
Thanks for letting me know, here's a patch to fix the wardning.
Regards,
Tony
Subject: ARM: OMAP: Fix warning in dma.c
Fix warning: 'offset' might be uninitialized
arch/arm/plat-omap/dma.c +1 -1
@@ -747,7 +747,7 @@ int omap_set_dma_callback(int lch,*/ dma_addr_t omap_get_dma_src_pos (int lch) { -dma_addr_t offset; +dma_addr_t offset =0 ;if (cpu_class_is_omap1 ()) offset = (dma_addr_t) (OMAP1_DMA_CSSA_L_REG(lch) |
Tony Lindgren
reviewerQuoted 6 lines · Tony Lindgren
Hi,
The following patch series contains GPIO updates for OMAP.
This is take #2 of the earlier 90 patch mountain, which has been split into six smaller series.
Also please note that this series only has 9 patches total, not 10 like the subject says.
Tony