Release 4.12 drivers/gpio/gpio-omap.c
  
  
  
/*
 * Support functions for OMAP GPIO
 *
 * Copyright (C) 2003-2005 Nokia Corporation
 * Written by Juha Yrjölä <juha.yrjola@nokia.com>
 *
 * Copyright (C) 2009 Texas Instruments
 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/syscore_ops.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/pm_runtime.h>
#include <linux/pm.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/gpio.h>
#include <linux/bitops.h>
#include <linux/platform_data/gpio-omap.h>
#define OFF_MODE	1
#define OMAP4_GPIO_DEBOUNCINGTIME_MASK 0xFF
static LIST_HEAD(omap_gpio_list);
struct gpio_regs {
	
u32 irqenable1;
	
u32 irqenable2;
	
u32 wake_en;
	
u32 ctrl;
	
u32 oe;
	
u32 leveldetect0;
	
u32 leveldetect1;
	
u32 risingdetect;
	
u32 fallingdetect;
	
u32 dataout;
	
u32 debounce;
	
u32 debounce_en;
};
struct gpio_bank {
	
struct list_head node;
	
void __iomem *base;
	
int irq;
	
u32 non_wakeup_gpios;
	
u32 enabled_non_wakeup_gpios;
	
struct gpio_regs context;
	
u32 saved_datain;
	
u32 level_mask;
	
u32 toggle_mask;
	
raw_spinlock_t lock;
	
raw_spinlock_t wa_lock;
	
struct gpio_chip chip;
	
struct clk *dbck;
	
u32 mod_usage;
	
u32 irq_usage;
	
u32 dbck_enable_mask;
	
bool dbck_enabled;
	
bool is_mpuio;
	
bool dbck_flag;
	
bool loses_context;
	
bool context_valid;
	
int stride;
	
u32 width;
	
int context_loss_count;
	
int power_mode;
	
bool workaround_enabled;
	
void (*set_dataout)(struct gpio_bank *bank, unsigned gpio, int enable);
	
int (*get_context_loss_count)(struct device *dev);
	
struct omap_gpio_reg_offs *regs;
};
#define GPIO_MOD_CTRL_BIT	BIT(0)
#define BANK_USED(bank) (bank->mod_usage || bank->irq_usage)
#define LINE_USED(line, offset) (line & (BIT(offset)))
static void omap_gpio_unmask_irq(struct irq_data *d);
static inline struct gpio_bank *omap_irq_data_get_bank(struct irq_data *d)
{
	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
	return gpiochip_get_data(chip);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Javier Martinez Canillas | 15 | 50.00% | 2 | 40.00% | 
| Jon Hunter | 12 | 40.00% | 1 | 20.00% | 
| Benoît Cousson | 2 | 6.67% | 1 | 20.00% | 
| Linus Walleij | 1 | 3.33% | 1 | 20.00% | 
| Total | 30 | 100.00% | 5 | 100.00% | 
static void omap_set_gpio_direction(struct gpio_bank *bank, int gpio,
				    int is_input)
{
	void __iomem *reg = bank->base;
	u32 l;
	reg += bank->regs->direction;
	l = readl_relaxed(reg);
	if (is_input)
		l |= BIT(gpio);
	else
		l &= ~(BIT(gpio));
	writel_relaxed(l, reg);
	bank->context.oe = l;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Cory Maccarrone | 29 | 35.80% | 1 | 9.09% | 
| Varadarajan, Charulatha | 21 | 25.93% | 1 | 9.09% | 
| Tarun Kanti DebBarma | 8 | 9.88% | 1 | 9.09% | 
| Javier Martinez Canillas | 7 | 8.64% | 2 | 18.18% | 
| Tony Lindgren | 6 | 7.41% | 2 | 18.18% | 
| Kevin Hilman | 3 | 3.70% | 1 | 9.09% | 
| Syed Rafiuddin | 3 | 3.70% | 1 | 9.09% | 
| Victor Kamensky | 2 | 2.47% | 1 | 9.09% | 
| Felipe Balbi | 2 | 2.47% | 1 | 9.09% | 
| Total | 81 | 100.00% | 11 | 100.00% | 
/* set data out value using dedicate set/clear register */
static void omap_set_gpio_dataout_reg(struct gpio_bank *bank, unsigned offset,
				      int enable)
{
	void __iomem *reg = bank->base;
	u32 l = BIT(offset);
	if (enable) {
		reg += bank->regs->set_dataout;
		bank->context.dataout |= l;
	} else {
		reg += bank->regs->clr_dataout;
		bank->context.dataout &= ~l;
	}
	writel_relaxed(l, reg);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tony Lindgren | 30 | 36.14% | 3 | 27.27% | 
| Tarun Kanti DebBarma | 21 | 25.30% | 1 | 9.09% | 
| Kevin Hilman | 13 | 15.66% | 1 | 9.09% | 
| Varadarajan, Charulatha | 11 | 13.25% | 1 | 9.09% | 
| Grygorii Strashko | 4 | 4.82% | 1 | 9.09% | 
| Syed Rafiuddin | 1 | 1.20% | 1 | 9.09% | 
| Javier Martinez Canillas | 1 | 1.20% | 1 | 9.09% | 
| Victor Kamensky | 1 | 1.20% | 1 | 9.09% | 
| Juha Yrjölä | 1 | 1.20% | 1 | 9.09% | 
| Total | 83 | 100.00% | 11 | 100.00% | 
/* set data out value using mask register */
static void omap_set_gpio_dataout_mask(struct gpio_bank *bank, unsigned offset,
				       int enable)
{
	void __iomem *reg = bank->base + bank->regs->dataout;
	u32 gpio_bit = BIT(offset);
	u32 l;
	l = readl_relaxed(reg);
	if (enable)
		l |= gpio_bit;
	else
		l &= ~gpio_bit;
	writel_relaxed(l, reg);
	bank->context.dataout = l;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Kevin Hilman | 35 | 44.30% | 2 | 22.22% | 
| Varadarajan, Charulatha | 16 | 20.25% | 1 | 11.11% | 
| Tony Lindgren | 9 | 11.39% | 1 | 11.11% | 
| Tarun Kanti DebBarma | 8 | 10.13% | 1 | 11.11% | 
| Syed Rafiuddin | 4 | 5.06% | 1 | 11.11% | 
| Grygorii Strashko | 4 | 5.06% | 1 | 11.11% | 
| Victor Kamensky | 2 | 2.53% | 1 | 11.11% | 
| Javier Martinez Canillas | 1 | 1.27% | 1 | 11.11% | 
| Total | 79 | 100.00% | 9 | 100.00% | 
static int omap_get_gpio_datain(struct gpio_bank *bank, int offset)
{
	void __iomem *reg = bank->base + bank->regs->datain;
	return (readl_relaxed(reg) & (BIT(offset))) != 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Cory Maccarrone | 18 | 39.13% | 1 | 10.00% | 
| Varadarajan, Charulatha | 9 | 19.57% | 1 | 10.00% | 
| Kevin Hilman | 7 | 15.22% | 1 | 10.00% | 
| Tarun Kanti DebBarma | 4 | 8.70% | 1 | 10.00% | 
| Javier Martinez Canillas | 4 | 8.70% | 2 | 20.00% | 
| Zebediah C. McClure | 1 | 2.17% | 1 | 10.00% | 
| Tony Lindgren | 1 | 2.17% | 1 | 10.00% | 
| Victor Kamensky | 1 | 2.17% | 1 | 10.00% | 
| Janusz Krzysztofik | 1 | 2.17% | 1 | 10.00% | 
| Total | 46 | 100.00% | 10 | 100.00% | 
static int omap_get_gpio_dataout(struct gpio_bank *bank, int offset)
{
	void __iomem *reg = bank->base + bank->regs->dataout;
	return (readl_relaxed(reg) & (BIT(offset))) != 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 21 | 45.65% | 1 | 12.50% | 
| Kevin Hilman | 10 | 21.74% | 1 | 12.50% | 
| Tony Lindgren | 6 | 13.04% | 2 | 25.00% | 
| Javier Martinez Canillas | 4 | 8.70% | 2 | 25.00% | 
| Tarun Kanti DebBarma | 4 | 8.70% | 1 | 12.50% | 
| Victor Kamensky | 1 | 2.17% | 1 | 12.50% | 
| Total | 46 | 100.00% | 8 | 100.00% | 
static inline void omap_gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
{
	int l = readl_relaxed(base + reg);
	if (set)
		l |= mask;
	else
		l &= ~mask;
	writel_relaxed(l, base + reg);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Kevin Hilman | 45 | 83.33% | 1 | 25.00% | 
| Varadarajan, Charulatha | 6 | 11.11% | 1 | 25.00% | 
| Victor Kamensky | 2 | 3.70% | 1 | 25.00% | 
| Javier Martinez Canillas | 1 | 1.85% | 1 | 25.00% | 
| Total | 54 | 100.00% | 4 | 100.00% | 
static inline void omap_gpio_dbck_enable(struct gpio_bank *bank)
{
	if (bank->dbck_enable_mask && !bank->dbck_enabled) {
		clk_enable(bank->dbck);
		bank->dbck_enabled = true;
		writel_relaxed(bank->dbck_enable_mask,
			     bank->base + bank->regs->debounce_en);
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tarun Kanti DebBarma | 36 | 65.45% | 1 | 20.00% | 
| Grazvydas Ignotas | 16 | 29.09% | 1 | 20.00% | 
| Grygorii Strashko | 1 | 1.82% | 1 | 20.00% | 
| Javier Martinez Canillas | 1 | 1.82% | 1 | 20.00% | 
| Victor Kamensky | 1 | 1.82% | 1 | 20.00% | 
| Total | 55 | 100.00% | 5 | 100.00% | 
static inline void omap_gpio_dbck_disable(struct gpio_bank *bank)
{
	if (bank->dbck_enable_mask && bank->dbck_enabled) {
		/*
                 * Disable debounce before cutting it's clock. If debounce is
                 * enabled but the clock is not, GPIO module seems to be unable
                 * to detect events and generate interrupts at least on OMAP3.
                 */
		writel_relaxed(0, bank->base + bank->regs->debounce_en);
		clk_disable(bank->dbck);
		bank->dbck_enabled = false;
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tarun Kanti DebBarma | 35 | 66.04% | 1 | 20.00% | 
| Grazvydas Ignotas | 15 | 28.30% | 1 | 20.00% | 
| Grygorii Strashko | 1 | 1.89% | 1 | 20.00% | 
| Victor Kamensky | 1 | 1.89% | 1 | 20.00% | 
| Javier Martinez Canillas | 1 | 1.89% | 1 | 20.00% | 
| Total | 53 | 100.00% | 5 | 100.00% | 
/**
 * omap2_set_gpio_debounce - low level gpio debounce time
 * @bank: the gpio bank we're acting upon
 * @offset: the gpio number on this @bank
 * @debounce: debounce time to use
 *
 * OMAP's debounce time is in 31us steps
 *   <debounce time> = (GPIO_DEBOUNCINGTIME[7:0].DEBOUNCETIME + 1) x 31
 * so we need to convert and round up to the closest unit.
 *
 * Return: 0 on success, negative error otherwise.
 */
static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
				   unsigned debounce)
{
	void __iomem		*reg;
	u32			val;
	u32			l;
	bool			enable = !!debounce;
	if (!bank->dbck_flag)
		return -ENOTSUPP;
	if (enable) {
		debounce = DIV_ROUND_UP(debounce, 31) - 1;
		if ((debounce & OMAP4_GPIO_DEBOUNCINGTIME_MASK) != debounce)
			return -EINVAL;
	}
	l = BIT(offset);
	clk_enable(bank->dbck);
	reg = bank->base + bank->regs->debounce;
	writel_relaxed(debounce, reg);
	reg = bank->base + bank->regs->debounce_en;
	val = readl_relaxed(reg);
	if (enable)
		val |= l;
	else
		val &= ~l;
	bank->dbck_enable_mask = val;
	writel_relaxed(val, reg);
	clk_disable(bank->dbck);
	/*
         * Enable debounce clock per module.
         * This call is mandatory because in omap_gpio_request() when
         * *_runtime_get_sync() is called,  _gpio_dbck_enable() within
         * runtime callbck fails to turn on dbck because dbck_enable_mask
         * used within _gpio_dbck_enable() is still not initialized at
         * that point. Therefore we have to enable dbck here.
         */
	omap_gpio_dbck_enable(bank);
	if (bank->dbck_enable_mask) {
		bank->context.debounce = debounce;
		bank->context.debounce_en = val;
	}
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 54 | 27.55% | 1 | 6.25% | 
| Tony Lindgren | 29 | 14.80% | 2 | 12.50% | 
| Nishanth Menon | 24 | 12.24% | 1 | 6.25% | 
| Grygorii Strashko | 23 | 11.73% | 3 | 18.75% | 
| David Rivshin | 20 | 10.20% | 1 | 6.25% | 
| Kevin Hilman | 17 | 8.67% | 2 | 12.50% | 
| Tarun Kanti DebBarma | 17 | 8.67% | 1 | 6.25% | 
| David Brownell | 7 | 3.57% | 3 | 18.75% | 
| Victor Kamensky | 3 | 1.53% | 1 | 6.25% | 
| Javier Martinez Canillas | 2 | 1.02% | 1 | 6.25% | 
| Total | 196 | 100.00% | 16 | 100.00% | 
/**
 * omap_clear_gpio_debounce - clear debounce settings for a gpio
 * @bank: the gpio bank we're acting upon
 * @offset: the gpio number on this @bank
 *
 * If a gpio is using debounce, then clear the debounce enable bit and if
 * this is the only gpio in this bank using debounce, then clear the debounce
 * time too. The debounce clock will also be disabled when calling this function
 * if this is the only gpio in the bank using debounce.
 */
static void omap_clear_gpio_debounce(struct gpio_bank *bank, unsigned offset)
{
	u32 gpio_bit = BIT(offset);
	if (!bank->dbck_flag)
		return;
	if (!(bank->dbck_enable_mask & gpio_bit))
		return;
	bank->dbck_enable_mask &= ~gpio_bit;
	bank->context.debounce_en &= ~gpio_bit;
        writel_relaxed(bank->context.debounce_en,
		     bank->base + bank->regs->debounce_en);
	if (!bank->dbck_enable_mask) {
		bank->context.debounce = 0;
		writel_relaxed(bank->context.debounce, bank->base +
			     bank->regs->debounce);
		clk_disable(bank->dbck);
		bank->dbck_enabled = false;
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Jon Hunter | 119 | 94.44% | 1 | 20.00% | 
| Grygorii Strashko | 4 | 3.17% | 2 | 40.00% | 
| Victor Kamensky | 2 | 1.59% | 1 | 20.00% | 
| Javier Martinez Canillas | 1 | 0.79% | 1 | 20.00% | 
| Total | 126 | 100.00% | 5 | 100.00% | 
static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
						unsigned trigger)
{
	void __iomem *base = bank->base;
	u32 gpio_bit = BIT(gpio);
	omap_gpio_rmw(base, bank->regs->leveldetect0, gpio_bit,
		      trigger & IRQ_TYPE_LEVEL_LOW);
	omap_gpio_rmw(base, bank->regs->leveldetect1, gpio_bit,
		      trigger & IRQ_TYPE_LEVEL_HIGH);
	omap_gpio_rmw(base, bank->regs->risingdetect, gpio_bit,
		      trigger & IRQ_TYPE_EDGE_RISING);
	omap_gpio_rmw(base, bank->regs->fallingdetect, gpio_bit,
		      trigger & IRQ_TYPE_EDGE_FALLING);
	bank->context.leveldetect0 =
			readl_relaxed(bank->base + bank->regs->leveldetect0);
	bank->context.leveldetect1 =
			readl_relaxed(bank->base + bank->regs->leveldetect1);
	bank->context.risingdetect =
			readl_relaxed(bank->base + bank->regs->risingdetect);
	bank->context.fallingdetect =
			readl_relaxed(bank->base + bank->regs->fallingdetect);
	if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
		omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
		bank->context.wake_en =
			readl_relaxed(bank->base + bank->regs->wkup_en);
	}
	/* This part needs to be executed always for OMAP{34xx, 44xx} */
	if (!bank->regs->irqctrl) {
		/* On omap24xx proceed only when valid GPIO bit is set */
		if (bank->non_wakeup_gpios) {
			if (!(bank->non_wakeup_gpios & gpio_bit))
				goto exit;
		}
		/*
                 * Log the edge gpio and manually trigger the IRQ
                 * after resume if the input level changes
                 * to avoid irq lost during PER RET/OFF mode
                 * Applies for omap2 non-wakeup gpio and all omap3 gpios
                 */
		if (trigger & IRQ_TYPE_EDGE_BOTH)
			bank->enabled_non_wakeup_gpios |= gpio_bit;
		else
			bank->enabled_non_wakeup_gpios &= ~gpio_bit;
	}
exit:
	bank->level_mask =
		readl_relaxed(bank->base + bank->regs->leveldetect0) |
		readl_relaxed(bank->base + bank->regs->leveldetect1);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tarun Kanti DebBarma | 145 | 45.45% | 4 | 20.00% | 
| Varadarajan, Charulatha | 101 | 31.66% | 1 | 5.00% | 
| Tony Lindgren | 27 | 8.46% | 3 | 15.00% | 
| Kevin Hilman | 10 | 3.13% | 1 | 5.00% | 
| Javier Martinez Canillas | 9 | 2.82% | 2 | 10.00% | 
| Victor Kamensky | 7 | 2.19% | 1 | 5.00% | 
| Colin Cross | 5 | 1.57% | 1 | 5.00% | 
| Alistair Buxton | 4 | 1.25% | 1 | 5.00% | 
| Syed Mohammed Khasim | 3 | 0.94% | 1 | 5.00% | 
| Syed Rafiuddin | 3 | 0.94% | 1 | 5.00% | 
| Roger Quadros | 2 | 0.63% | 1 | 5.00% | 
| David Brownell | 1 | 0.31% | 1 | 5.00% | 
| Hiroshi Doyu | 1 | 0.31% | 1 | 5.00% | 
| Zebediah C. McClure | 1 | 0.31% | 1 | 5.00% | 
| Total | 319 | 100.00% | 20 | 100.00% | 
#ifdef CONFIG_ARCH_OMAP1
/*
 * This only applies to chips that can't do both rising and falling edge
 * detection at once.  For all other chips, this function is a noop.
 */
static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
{
	void __iomem *reg = bank->base;
	u32 l = 0;
	if (!bank->regs->irqctrl)
		return;
	reg += bank->regs->irqctrl;
	l = readl_relaxed(reg);
	if ((l >> gpio) & 1)
		l &= ~(BIT(gpio));
	else
		l |= BIT(gpio);
	writel_relaxed(l, reg);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Imre Deak | 43 | 48.86% | 2 | 25.00% | 
| Varadarajan, Charulatha | 25 | 28.41% | 1 | 12.50% | 
| Tarun Kanti DebBarma | 9 | 10.23% | 1 | 12.50% | 
| Javier Martinez Canillas | 7 | 7.95% | 2 | 25.00% | 
| Victor Kamensky | 2 | 2.27% | 1 | 12.50% | 
| Tony Lindgren | 2 | 2.27% | 1 | 12.50% | 
| Total | 88 | 100.00% | 8 | 100.00% | 
#else
static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) {}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tarun Kanti DebBarma | 12 | 92.31% | 1 | 50.00% | 
| Javier Martinez Canillas | 1 | 7.69% | 1 | 50.00% | 
| Total | 13 | 100.00% | 2 | 100.00% | 
#endif
static int omap_set_gpio_triggering(struct gpio_bank *bank, int gpio,
				    unsigned trigger)
{
	void __iomem *reg = bank->base;
	void __iomem *base = bank->base;
	u32 l = 0;
	if (bank->regs->leveldetect0 && bank->regs->wkup_en) {
		omap_set_gpio_trigger(bank, gpio, trigger);
	} else if (bank->regs->irqctrl) {
		reg += bank->regs->irqctrl;
		l = readl_relaxed(reg);
		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
			bank->toggle_mask |= BIT(gpio);
		if (trigger & IRQ_TYPE_EDGE_RISING)
			l |= BIT(gpio);
		else if (trigger & IRQ_TYPE_EDGE_FALLING)
			l &= ~(BIT(gpio));
		else
			return -EINVAL;
		writel_relaxed(l, reg);
	} else if (bank->regs->edgectrl1) {
		if (gpio & 0x08)
			reg += bank->regs->edgectrl2;
		else
			reg += bank->regs->edgectrl1;
		gpio &= 0x07;
		l = readl_relaxed(reg);
		l &= ~(3 << (gpio << 1));
		if (trigger & IRQ_TYPE_EDGE_RISING)
			l |= 2 << (gpio << 1);
		if (trigger & IRQ_TYPE_EDGE_FALLING)
			l |= BIT(gpio << 1);
		/* Enable wake-up during idle for dynamic tick */
		omap_gpio_rmw(base, bank->regs->wkup_en, BIT(gpio), trigger);
		bank->context.wake_en =
			readl_relaxed(bank->base + bank->regs->wkup_en);
		writel_relaxed(l, reg);
	}
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 104 | 35.99% | 1 | 9.09% | 
| Tarun Kanti DebBarma | 86 | 29.76% | 3 | 27.27% | 
| Tony Lindgren | 75 | 25.95% | 3 | 27.27% | 
| Javier Martinez Canillas | 18 | 6.23% | 2 | 18.18% | 
| Victor Kamensky | 5 | 1.73% | 1 | 9.09% | 
| Syed Rafiuddin | 1 | 0.35% | 1 | 9.09% | 
| Total | 289 | 100.00% | 11 | 100.00% | 
static void omap_enable_gpio_module(struct gpio_bank *bank, unsigned offset)
{
	if (bank->regs->pinctrl) {
		void __iomem *reg = bank->base + bank->regs->pinctrl;
		/* Claim the pin for MPU */
		writel_relaxed(readl_relaxed(reg) | (BIT(offset)), reg);
	}
	if (bank->regs->ctrl && !BANK_USED(bank)) {
		void __iomem *reg = bank->base + bank->regs->ctrl;
		u32 ctrl;
		ctrl = readl_relaxed(reg);
		/* Module is enabled, clocks are not gated */
		ctrl &= ~GPIO_MOD_CTRL_BIT;
		writel_relaxed(ctrl, reg);
		bank->context.ctrl = ctrl;
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Javier Martinez Canillas | 115 | 96.64% | 3 | 75.00% | 
| Victor Kamensky | 4 | 3.36% | 1 | 25.00% | 
| Total | 119 | 100.00% | 4 | 100.00% | 
static void omap_disable_gpio_module(struct gpio_bank *bank, unsigned offset)
{
	void __iomem *base = bank->base;
	if (bank->regs->wkup_en &&
	    !LINE_USED(bank->mod_usage, offset) &&
	    !LINE_USED(bank->irq_usage, offset)) {
		/* Disable wake-up during idle for dynamic tick */
		omap_gpio_rmw(base, bank->regs->wkup_en, BIT(offset), 0);
		bank->context.wake_en =
			readl_relaxed(bank->base + bank->regs->wkup_en);
	}
	if (bank->regs->ctrl && !BANK_USED(bank)) {
		void __iomem *reg = bank->base + bank->regs->ctrl;
		u32 ctrl;
		ctrl = readl_relaxed(reg);
		/* Module is disabled, clocks are gated */
		ctrl |= GPIO_MOD_CTRL_BIT;
		writel_relaxed(ctrl, reg);
		bank->context.ctrl = ctrl;
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Javier Martinez Canillas | 149 | 98.03% | 3 | 75.00% | 
| Victor Kamensky | 3 | 1.97% | 1 | 25.00% | 
| Total | 152 | 100.00% | 4 | 100.00% | 
static int omap_gpio_is_input(struct gpio_bank *bank, unsigned offset)
{
	void __iomem *reg = bank->base + bank->regs->direction;
	return readl_relaxed(reg) & BIT(offset);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Javier Martinez Canillas | 33 | 82.50% | 2 | 50.00% | 
| Grygorii Strashko | 6 | 15.00% | 1 | 25.00% | 
| Victor Kamensky | 1 | 2.50% | 1 | 25.00% | 
| Total | 40 | 100.00% | 4 | 100.00% | 
static void omap_gpio_init_irq(struct gpio_bank *bank, unsigned offset)
{
	if (!LINE_USED(bank->mod_usage, offset)) {
		omap_enable_gpio_module(bank, offset);
		omap_set_gpio_direction(bank, offset, 1);
	}
	bank->irq_usage |= BIT(offset);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tony Lindgren | 52 | 98.11% | 1 | 50.00% | 
| Grygorii Strashko | 1 | 1.89% | 1 | 50.00% | 
| Total | 53 | 100.00% | 2 | 100.00% | 
static int omap_gpio_irq_type(struct irq_data *d, unsigned type)
{
	struct gpio_bank *bank = omap_irq_data_get_bank(d);
	int retval;
	unsigned long flags;
	unsigned offset = d->hwirq;
	if (type & ~IRQ_TYPE_SENSE_MASK)
		return -EINVAL;
	if (!bank->regs->leveldetect0 &&
		(type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
		return -EINVAL;
	raw_spin_lock_irqsave(&bank->lock, flags);
	retval = omap_set_gpio_triggering(bank, offset, type);
	if (retval) {
		raw_spin_unlock_irqrestore(&bank->lock, flags);
		goto error;
	}
	omap_gpio_init_irq(bank, offset);
	if (!omap_gpio_is_input(bank, offset)) {
		raw_spin_unlock_irqrestore(&bank->lock, flags);
		retval = -EINVAL;
		goto error;
	}
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
		irq_set_handler_locked(d, handle_level_irq);
	else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
		irq_set_handler_locked(d, handle_edge_irq);
	return 0;
error:
	return retval;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 56 | 27.72% | 1 | 4.76% | 
| Javier Martinez Canillas | 35 | 17.33% | 2 | 9.52% | 
| Grygorii Strashko | 33 | 16.34% | 3 | 14.29% | 
| Tony Lindgren | 26 | 12.87% | 4 | 19.05% | 
| Juha Yrjölä | 16 | 7.92% | 1 | 4.76% | 
| David Brownell | 11 | 5.45% | 2 | 9.52% | 
| Lennert Buytenhek | 6 | 2.97% | 1 | 4.76% | 
| Tarun Kanti DebBarma | 5 | 2.48% | 1 | 4.76% | 
| Benoît Cousson | 4 | 1.98% | 1 | 4.76% | 
| Sebastian Andrzej Siewior | 3 | 1.49% | 1 | 4.76% | 
| Jon Hunter | 2 | 0.99% | 1 | 4.76% | 
| Thomas Gleixner | 2 | 0.99% | 1 | 4.76% | 
| Kevin Hilman | 2 | 0.99% | 1 | 4.76% | 
| Axel Lin | 1 | 0.50% | 1 | 4.76% | 
| Total | 202 | 100.00% | 21 | 100.00% | 
static void omap_clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
{
	void __iomem *reg = bank->base;
	reg += bank->regs->irqstatus;
	writel_relaxed(gpio_mask, reg);
	/* Workaround for clearing DSP GPIO interrupts to allow retention */
	if (bank->regs->irqstatus2) {
		reg = bank->base + bank->regs->irqstatus2;
		writel_relaxed(gpio_mask, reg);
	}
	/* Flush posted write for the irq status to avoid spurious interrupts */
	readl_relaxed(reg);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 36 | 48.65% | 1 | 16.67% | 
| Kevin Hilman | 15 | 20.27% | 1 | 16.67% | 
| Juha Yrjölä | 12 | 16.22% | 1 | 16.67% | 
| Tony Lindgren | 7 | 9.46% | 1 | 16.67% | 
| Victor Kamensky | 3 | 4.05% | 1 | 16.67% | 
| Javier Martinez Canillas | 1 | 1.35% | 1 | 16.67% | 
| Total | 74 | 100.00% | 6 | 100.00% | 
static inline void omap_clear_gpio_irqstatus(struct gpio_bank *bank,
					     unsigned offset)
{
	omap_clear_gpio_irqbank(bank, BIT(offset));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tony Lindgren | 14 | 56.00% | 2 | 40.00% | 
| Varadarajan, Charulatha | 5 | 20.00% | 1 | 20.00% | 
| Grygorii Strashko | 4 | 16.00% | 1 | 20.00% | 
| Javier Martinez Canillas | 2 | 8.00% | 1 | 20.00% | 
| Total | 25 | 100.00% | 5 | 100.00% | 
static u32 omap_get_gpio_irqbank_mask(struct gpio_bank *bank)
{
	void __iomem *reg = bank->base;
	u32 l;
	u32 mask = (BIT(bank->width)) - 1;
	reg += bank->regs->irqenable;
	l = readl_relaxed(reg);
	if (bank->regs->irqenable_inv)
		l = ~l;
	l &= mask;
	return l;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 36 | 50.00% | 2 | 16.67% | 
| Kevin Hilman | 14 | 19.44% | 2 | 16.67% | 
| Tony Lindgren | 13 | 18.06% | 3 | 25.00% | 
| Javier Martinez Canillas | 4 | 5.56% | 2 | 16.67% | 
| Jarkko Nikula | 3 | 4.17% | 1 | 8.33% | 
| David Brownell | 1 | 1.39% | 1 | 8.33% | 
| Victor Kamensky | 1 | 1.39% | 1 | 8.33% | 
| Total | 72 | 100.00% | 12 | 100.00% | 
static void omap_enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
{
	void __iomem *reg = bank->base;
	u32 l;
	if (bank->regs->set_irqenable) {
		reg += bank->regs->set_irqenable;
		l = gpio_mask;
		bank->context.irqenable1 |= gpio_mask;
	} else {
		reg += bank->regs->irqenable;
		l = readl_relaxed(reg);
		if (bank->regs->irqenable_inv)
			l &= ~gpio_mask;
		else
			l |= gpio_mask;
		bank->context.irqenable1 = l;
	}
	writel_relaxed(l, reg);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 53 | 49.53% | 3 | 27.27% | 
| Tarun Kanti DebBarma | 23 | 21.50% | 2 | 18.18% | 
| Kevin Hilman | 19 | 17.76% | 1 | 9.09% | 
| Tony Lindgren | 9 | 8.41% | 3 | 27.27% | 
| Victor Kamensky | 2 | 1.87% | 1 | 9.09% | 
| Javier Martinez Canillas | 1 | 0.93% | 1 | 9.09% | 
| Total | 107 | 100.00% | 11 | 100.00% | 
static void omap_disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
{
	void __iomem *reg = bank->base;
	u32 l;
	if (bank->regs->clr_irqenable) {
		reg += bank->regs->clr_irqenable;
		l = gpio_mask;
		bank->context.irqenable1 &= ~gpio_mask;
	} else {
		reg += bank->regs->irqenable;
		l = readl_relaxed(reg);
		if (bank->regs->irqenable_inv)
			l |= gpio_mask;
		else
			l &= ~gpio_mask;
		bank->context.irqenable1 = l;
	}
	writel_relaxed(l, reg);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Kevin Hilman | 49 | 45.37% | 1 | 10.00% | 
| Varadarajan, Charulatha | 28 | 25.93% | 3 | 30.00% | 
| Tarun Kanti DebBarma | 24 | 22.22% | 2 | 20.00% | 
| Tony Lindgren | 4 | 3.70% | 2 | 20.00% | 
| Victor Kamensky | 2 | 1.85% | 1 | 10.00% | 
| Javier Martinez Canillas | 1 | 0.93% | 1 | 10.00% | 
| Total | 108 | 100.00% | 10 | 100.00% | 
static inline void omap_set_gpio_irqenable(struct gpio_bank *bank,
					   unsigned offset, int enable)
{
	if (enable)
		omap_enable_gpio_irqbank(bank, BIT(offset));
	else
		omap_disable_gpio_irqbank(bank, BIT(offset));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 16 | 37.21% | 1 | 16.67% | 
| Tarun Kanti DebBarma | 12 | 27.91% | 1 | 16.67% | 
| Tony Lindgren | 6 | 13.95% | 2 | 33.33% | 
| Grygorii Strashko | 6 | 13.95% | 1 | 16.67% | 
| Javier Martinez Canillas | 3 | 6.98% | 1 | 16.67% | 
| Total | 43 | 100.00% | 6 | 100.00% | 
/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
static int omap_gpio_wake_enable(struct irq_data *d, unsigned int enable)
{
	struct gpio_bank *bank = omap_irq_data_get_bank(d);
	return irq_set_irq_wake(bank->irq, enable);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 16 | 45.71% | 1 | 16.67% | 
| Grygorii Strashko | 9 | 25.71% | 2 | 33.33% | 
| Benoît Cousson | 4 | 11.43% | 1 | 16.67% | 
| Lennert Buytenhek | 4 | 11.43% | 1 | 16.67% | 
| Javier Martinez Canillas | 2 | 5.71% | 1 | 16.67% | 
| Total | 35 | 100.00% | 6 | 100.00% | 
static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
{
	struct gpio_bank *bank = gpiochip_get_data(chip);
	unsigned long flags;
	/*
         * If this is the first gpio_request for the bank,
         * enable the bank module.
         */
	if (!BANK_USED(bank))
		pm_runtime_get_sync(chip->parent);
	raw_spin_lock_irqsave(&bank->lock, flags);
	omap_enable_gpio_module(bank, offset);
	bank->mod_usage |= BIT(offset);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 33 | 39.76% | 2 | 14.29% | 
| Javier Martinez Canillas | 30 | 36.14% | 4 | 28.57% | 
| Tony Lindgren | 9 | 10.84% | 3 | 21.43% | 
| Imre Deak | 4 | 4.82% | 1 | 7.14% | 
| Sebastian Andrzej Siewior | 2 | 2.41% | 1 | 7.14% | 
| Tarun Kanti DebBarma | 2 | 2.41% | 1 | 7.14% | 
| Grygorii Strashko | 2 | 2.41% | 1 | 7.14% | 
| Linus Walleij | 1 | 1.20% | 1 | 7.14% | 
| Total | 83 | 100.00% | 14 | 100.00% | 
static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
{
	struct gpio_bank *bank = gpiochip_get_data(chip);
	unsigned long flags;
	raw_spin_lock_irqsave(&bank->lock, flags);
	bank->mod_usage &= ~(BIT(offset));
	if (!LINE_USED(bank->irq_usage, offset)) {
		omap_set_gpio_direction(bank, offset, 1);
		omap_clear_gpio_debounce(bank, offset);
	}
	omap_disable_gpio_module(bank, offset);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	/*
         * If this is the last gpio to be freed in the bank,
         * disable the bank module.
         */
	if (!BANK_USED(bank))
		pm_runtime_put(chip->parent);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 43 | 38.05% | 1 | 7.69% | 
| Grygorii Strashko | 27 | 23.89% | 2 | 15.38% | 
| Tarun Kanti DebBarma | 13 | 11.50% | 2 | 15.38% | 
| Tony Lindgren | 10 | 8.85% | 1 | 7.69% | 
| Javier Martinez Canillas | 8 | 7.08% | 3 | 23.08% | 
| Kevin Hilman | 5 | 4.42% | 1 | 7.69% | 
| Cory Maccarrone | 4 | 3.54% | 1 | 7.69% | 
| Sebastian Andrzej Siewior | 2 | 1.77% | 1 | 7.69% | 
| Linus Walleij | 1 | 0.88% | 1 | 7.69% | 
| Total | 113 | 100.00% | 13 | 100.00% | 
/*
 * We need to unmask the GPIO bank interrupt as soon as possible to
 * avoid missing GPIO interrupts for other lines in the bank.
 * Then we need to mask-read-clear-unmask the triggered GPIO lines
 * in the bank to avoid missing nested interrupts for a GPIO line.
 * If we wait to unmask individual GPIO lines in the bank after the
 * line's interrupt handler has been run, we may miss some nested
 * interrupts.
 */
static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
{
	void __iomem *isr_reg = NULL;
	u32 isr;
	unsigned int bit;
	struct gpio_bank *bank = gpiobank;
	unsigned long wa_lock_flags;
	unsigned long lock_flags;
	isr_reg = bank->base + bank->regs->irqstatus;
	if (WARN_ON(!isr_reg))
		goto exit;
	pm_runtime_get_sync(bank->chip.parent);
	while (1) {
		u32 isr_saved, level_mask = 0;
		u32 enabled;
		raw_spin_lock_irqsave(&bank->lock, lock_flags);
		enabled = omap_get_gpio_irqbank_mask(bank);
		isr_saved = isr = readl_relaxed(isr_reg) & enabled;
		if (bank->level_mask)
			level_mask = bank->level_mask & enabled;
		/* clear edge sensitive interrupts before handler(s) are
                called so that we don't miss any interrupt occurred while
                executing them */
		omap_disable_gpio_irqbank(bank, isr_saved & ~level_mask);
		omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
		omap_enable_gpio_irqbank(bank, isr_saved & ~level_mask);
		raw_spin_unlock_irqrestore(&bank->lock, lock_flags);
		if (!isr)
			break;
		while (isr) {
			bit = __ffs(isr);
			isr &= ~(BIT(bit));
			raw_spin_lock_irqsave(&bank->lock, lock_flags);
			/*
                         * Some chips can't respond to both rising and falling
                         * at the same time.  If this irq was requested with
                         * both flags, we need to flip the ICR data for the IRQ
                         * to respond to the IRQ for the opposite direction.
                         * This will be indicated in the bank toggle_mask.
                         */
			if (bank->toggle_mask & (BIT(bit)))
				omap_toggle_gpio_edge_triggering(bank, bit);
			raw_spin_unlock_irqrestore(&bank->lock, lock_flags);
			raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags);
			generic_handle_irq(irq_find_mapping(bank->chip.irqdomain,
							    bit));
			raw_spin_unlock_irqrestore(&bank->wa_lock,
						   wa_lock_flags);
		}
	}
exit:
	pm_runtime_put(bank->chip.parent);
	return IRQ_HANDLED;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 100 | 34.36% | 1 | 5.26% | 
| Grygorii Strashko | 89 | 30.58% | 3 | 15.79% | 
| David Brownell | 39 | 13.40% | 3 | 15.79% | 
| Jon Hunter | 20 | 6.87% | 2 | 10.53% | 
| Javier Martinez Canillas | 16 | 5.50% | 3 | 15.79% | 
| Tony Lindgren | 11 | 3.78% | 1 | 5.26% | 
| Tarun Kanti DebBarma | 9 | 3.09% | 2 | 10.53% | 
| Will Deacon | 3 | 1.03% | 1 | 5.26% | 
| Kevin Hilman | 2 | 0.69% | 1 | 5.26% | 
| Benoît Cousson | 1 | 0.34% | 1 | 5.26% | 
| Victor Kamensky | 1 | 0.34% | 1 | 5.26% | 
| Total | 291 | 100.00% | 19 | 100.00% | 
static unsigned int omap_gpio_irq_startup(struct irq_data *d)
{
	struct gpio_bank *bank = omap_irq_data_get_bank(d);
	unsigned long flags;
	unsigned offset = d->hwirq;
	raw_spin_lock_irqsave(&bank->lock, flags);
	if (!LINE_USED(bank->mod_usage, offset))
		omap_set_gpio_direction(bank, offset, 1);
	else if (!omap_gpio_is_input(bank, offset))
		goto err;
	omap_enable_gpio_module(bank, offset);
	bank->irq_usage |= BIT(offset);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	omap_gpio_unmask_irq(d);
	return 0;
err:
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	return -EINVAL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Grygorii Strashko | 63 | 49.22% | 2 | 50.00% | 
| Tony Lindgren | 62 | 48.44% | 1 | 25.00% | 
| Sebastian Andrzej Siewior | 3 | 2.34% | 1 | 25.00% | 
| Total | 128 | 100.00% | 4 | 100.00% | 
static void omap_gpio_irq_shutdown(struct irq_data *d)
{
	struct gpio_bank *bank = omap_irq_data_get_bank(d);
	unsigned long flags;
	unsigned offset = d->hwirq;
	raw_spin_lock_irqsave(&bank->lock, flags);
	bank->irq_usage &= ~(BIT(offset));
	omap_set_gpio_irqenable(bank, offset, 0);
	omap_clear_gpio_irqstatus(bank, offset);
	omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
	if (!LINE_USED(bank->mod_usage, offset))
		omap_clear_gpio_debounce(bank, offset);
	omap_disable_gpio_module(bank, offset);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Grygorii Strashko | 44 | 38.26% | 3 | 21.43% | 
| Javier Martinez Canillas | 24 | 20.87% | 4 | 28.57% | 
| Colin Cross | 22 | 19.13% | 1 | 7.14% | 
| Varadarajan, Charulatha | 11 | 9.57% | 1 | 7.14% | 
| David Brownell | 5 | 4.35% | 2 | 14.29% | 
| Lennert Buytenhek | 5 | 4.35% | 1 | 7.14% | 
| Tony Lindgren | 2 | 1.74% | 1 | 7.14% | 
| Sebastian Andrzej Siewior | 2 | 1.74% | 1 | 7.14% | 
| Total | 115 | 100.00% | 14 | 100.00% | 
static void omap_gpio_irq_bus_lock(struct irq_data *data)
{
	struct gpio_bank *bank = omap_irq_data_get_bank(data);
	if (!BANK_USED(bank))
		pm_runtime_get_sync(bank->chip.parent);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Grygorii Strashko | 38 | 100.00% | 2 | 100.00% | 
| Total | 38 | 100.00% | 2 | 100.00% | 
static void gpio_irq_bus_sync_unlock(struct irq_data *data)
{
	struct gpio_bank *bank = omap_irq_data_get_bank(data);
	/*
         * If this is the last IRQ to be freed in the bank,
         * disable the bank module.
         */
	if (!BANK_USED(bank))
		pm_runtime_put(bank->chip.parent);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Grygorii Strashko | 23 | 58.97% | 2 | 50.00% | 
| Javier Martinez Canillas | 15 | 38.46% | 1 | 25.00% | 
| Varadarajan, Charulatha | 1 | 2.56% | 1 | 25.00% | 
| Total | 39 | 100.00% | 4 | 100.00% | 
static void omap_gpio_ack_irq(struct irq_data *d)
{
	struct gpio_bank *bank = omap_irq_data_get_bank(d);
	unsigned offset = d->hwirq;
	omap_clear_gpio_irqstatus(bank, offset);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 15 | 42.86% | 1 | 14.29% | 
| Benoît Cousson | 5 | 14.29% | 1 | 14.29% | 
| Lennert Buytenhek | 5 | 14.29% | 1 | 14.29% | 
| David Brownell | 4 | 11.43% | 1 | 14.29% | 
| Javier Martinez Canillas | 3 | 8.57% | 1 | 14.29% | 
| Grygorii Strashko | 2 | 5.71% | 1 | 14.29% | 
| Jon Hunter | 1 | 2.86% | 1 | 14.29% | 
| Total | 35 | 100.00% | 7 | 100.00% | 
static void omap_gpio_mask_irq(struct irq_data *d)
{
	struct gpio_bank *bank = omap_irq_data_get_bank(d);
	unsigned offset = d->hwirq;
	unsigned long flags;
	raw_spin_lock_irqsave(&bank->lock, flags);
	omap_set_gpio_irqenable(bank, offset, 0);
	omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Colin Cross | 22 | 31.43% | 1 | 10.00% | 
| David Brownell | 18 | 25.71% | 1 | 10.00% | 
| Varadarajan, Charulatha | 8 | 11.43% | 1 | 10.00% | 
| Lennert Buytenhek | 5 | 7.14% | 1 | 10.00% | 
| Benoît Cousson | 5 | 7.14% | 1 | 10.00% | 
| Javier Martinez Canillas | 4 | 5.71% | 1 | 10.00% | 
| Grygorii Strashko | 3 | 4.29% | 1 | 10.00% | 
| Sebastian Andrzej Siewior | 2 | 2.86% | 1 | 10.00% | 
| Roger Quadros | 2 | 2.86% | 1 | 10.00% | 
| Jon Hunter | 1 | 1.43% | 1 | 10.00% | 
| Total | 70 | 100.00% | 10 | 100.00% | 
static void omap_gpio_unmask_irq(struct irq_data *d)
{
	struct gpio_bank *bank = omap_irq_data_get_bank(d);
	unsigned offset = d->hwirq;
	u32 trigger = irqd_get_trigger_type(d);
	unsigned long flags;
	raw_spin_lock_irqsave(&bank->lock, flags);
	if (trigger)
		omap_set_gpio_triggering(bank, offset, trigger);
	/* For level-triggered GPIOs, the clearing must be done after
         * the HW source is cleared, thus after the handler has run */
	if (bank->level_mask & BIT(offset)) {
		omap_set_gpio_irqenable(bank, offset, 0);
		omap_clear_gpio_irqstatus(bank, offset);
	}
	omap_set_gpio_irqenable(bank, offset, 1);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 40 | 35.71% | 2 | 16.67% | 
| Colin Cross | 21 | 18.75% | 1 | 8.33% | 
| Roger Quadros | 15 | 13.39% | 1 | 8.33% | 
| Grygorii Strashko | 9 | 8.04% | 1 | 8.33% | 
| David Brownell | 6 | 5.36% | 1 | 8.33% | 
| Lennert Buytenhek | 6 | 5.36% | 1 | 8.33% | 
| Javier Martinez Canillas | 6 | 5.36% | 1 | 8.33% | 
| Benoît Cousson | 3 | 2.68% | 1 | 8.33% | 
| Thomas Gleixner | 3 | 2.68% | 1 | 8.33% | 
| Sebastian Andrzej Siewior | 2 | 1.79% | 1 | 8.33% | 
| Jon Hunter | 1 | 0.89% | 1 | 8.33% | 
| Total | 112 | 100.00% | 12 | 100.00% | 
/*---------------------------------------------------------------------*/
static int omap_mpuio_suspend_noirq(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct gpio_bank	*bank = platform_get_drvdata(pdev);
	void __iomem		*mask_reg = bank->base +
					OMAP_MPUIO_GPIO_MASKIT / bank->stride;
	unsigned long		flags;
	raw_spin_lock_irqsave(&bank->lock, flags);
	writel_relaxed(0xffff & ~bank->context.wake_en, mask_reg);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| David Brownell | 39 | 44.83% | 1 | 16.67% | 
| Varadarajan, Charulatha | 38 | 43.68% | 1 | 16.67% | 
| Tony Lindgren | 4 | 4.60% | 1 | 16.67% | 
| Tarun Kanti DebBarma | 3 | 3.45% | 1 | 16.67% | 
| Sebastian Andrzej Siewior | 2 | 2.30% | 1 | 16.67% | 
| Victor Kamensky | 1 | 1.15% | 1 | 16.67% | 
| Total | 87 | 100.00% | 6 | 100.00% | 
static int omap_mpuio_resume_noirq(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct gpio_bank	*bank = platform_get_drvdata(pdev);
	void __iomem		*mask_reg = bank->base +
					OMAP_MPUIO_GPIO_MASKIT / bank->stride;
	unsigned long		flags;
	raw_spin_lock_irqsave(&bank->lock, flags);
	writel_relaxed(bank->context.wake_en, mask_reg);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Felipe Balbi | 43 | 51.19% | 1 | 16.67% | 
| Varadarajan, Charulatha | 31 | 36.90% | 1 | 16.67% | 
| Tony Lindgren | 4 | 4.76% | 1 | 16.67% | 
| Tarun Kanti DebBarma | 3 | 3.57% | 1 | 16.67% | 
| Sebastian Andrzej Siewior | 2 | 2.38% | 1 | 16.67% | 
| Victor Kamensky | 1 | 1.19% | 1 | 16.67% | 
| Total | 84 | 100.00% | 6 | 100.00% | 
static const struct dev_pm_ops omap_mpuio_dev_pm_ops = {
	.suspend_noirq = omap_mpuio_suspend_noirq,
	.resume_noirq = omap_mpuio_resume_noirq,
};
/* use platform_driver for this. */
static struct platform_driver omap_mpuio_driver = {
	.driver		= {
		.name	= "mpuio",
		.pm	= &omap_mpuio_dev_pm_ops,
        },
};
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 omap_mpuio_init(struct gpio_bank *bank)
{
	platform_set_drvdata(&omap_mpuio_device, bank);
	if (platform_driver_register(&omap_mpuio_driver) == 0)
		(void) platform_device_register(&omap_mpuio_device);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 24 | 61.54% | 2 | 33.33% | 
| David Brownell | 10 | 25.64% | 1 | 16.67% | 
| Santosh Shilimkar | 2 | 5.13% | 1 | 16.67% | 
| Syed Mohammed Khasim | 2 | 5.13% | 1 | 16.67% | 
| Javier Martinez Canillas | 1 | 2.56% | 1 | 16.67% | 
| Total | 39 | 100.00% | 6 | 100.00% | 
/*---------------------------------------------------------------------*/
static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
	struct gpio_bank *bank;
	unsigned long flags;
	void __iomem *reg;
	int dir;
	bank = gpiochip_get_data(chip);
	reg = bank->base + bank->regs->direction;
	raw_spin_lock_irqsave(&bank->lock, flags);
	dir = !!(readl_relaxed(reg) & BIT(offset));
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	return dir;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Yegor Yefremov | 85 | 95.51% | 1 | 25.00% | 
| Sebastian Andrzej Siewior | 2 | 2.25% | 1 | 25.00% | 
| Linus Walleij | 1 | 1.12% | 1 | 25.00% | 
| Javier Martinez Canillas | 1 | 1.12% | 1 | 25.00% | 
| Total | 89 | 100.00% | 4 | 100.00% | 
static int omap_gpio_input(struct gpio_chip *chip, unsigned offset)
{
	struct gpio_bank *bank;
	unsigned long flags;
	bank = gpiochip_get_data(chip);
	raw_spin_lock_irqsave(&bank->lock, flags);
	omap_set_gpio_direction(bank, offset, 1);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 35 | 56.45% | 2 | 25.00% | 
| Tony Lindgren | 20 | 32.26% | 2 | 25.00% | 
| Syed Mohammed Khasim | 2 | 3.23% | 1 | 12.50% | 
| Javier Martinez Canillas | 2 | 3.23% | 1 | 12.50% | 
| Sebastian Andrzej Siewior | 2 | 3.23% | 1 | 12.50% | 
| Linus Walleij | 1 | 1.61% | 1 | 12.50% | 
| Total | 62 | 100.00% | 8 | 100.00% | 
static int omap_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	struct gpio_bank *bank;
	bank = gpiochip_get_data(chip);
	if (omap_gpio_is_input(bank, offset))
		return omap_get_gpio_datain(bank, offset);
	else
		return omap_get_gpio_dataout(bank, offset);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 32 | 61.54% | 3 | 33.33% | 
| Syed Mohammed Khasim | 10 | 19.23% | 1 | 11.11% | 
| Javier Martinez Canillas | 4 | 7.69% | 1 | 11.11% | 
| Tarun Kanti DebBarma | 2 | 3.85% | 1 | 11.11% | 
| Tony Lindgren | 2 | 3.85% | 1 | 11.11% | 
| Grygorii Strashko | 1 | 1.92% | 1 | 11.11% | 
| Linus Walleij | 1 | 1.92% | 1 | 11.11% | 
| Total | 52 | 100.00% | 9 | 100.00% | 
static int omap_gpio_output(struct gpio_chip *chip, unsigned offset, int value)
{
	struct gpio_bank *bank;
	unsigned long flags;
	bank = gpiochip_get_data(chip);
	raw_spin_lock_irqsave(&bank->lock, flags);
	bank->set_dataout(bank, offset, value);
	omap_set_gpio_direction(bank, offset, 0);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 54 | 71.05% | 2 | 25.00% | 
| Syed Mohammed Khasim | 13 | 17.11% | 1 | 12.50% | 
| Javier Martinez Canillas | 3 | 3.95% | 2 | 25.00% | 
| Kevin Hilman | 3 | 3.95% | 1 | 12.50% | 
| Sebastian Andrzej Siewior | 2 | 2.63% | 1 | 12.50% | 
| Linus Walleij | 1 | 1.32% | 1 | 12.50% | 
| Total | 76 | 100.00% | 8 | 100.00% | 
static int omap_gpio_debounce(struct gpio_chip *chip, unsigned offset,
			      unsigned debounce)
{
	struct gpio_bank *bank;
	unsigned long flags;
	int ret;
	bank = gpiochip_get_data(chip);
	raw_spin_lock_irqsave(&bank->lock, flags);
	ret = omap2_set_gpio_debounce(bank, offset, debounce);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	if (ret)
		dev_info(chip->parent,
			 "Could not set line %u debounce to %u microseconds (%d)",
			 offset, debounce, ret);
	return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 54 | 60.67% | 2 | 20.00% | 
| David Rivshin | 25 | 28.09% | 1 | 10.00% | 
| Tony Lindgren | 3 | 3.37% | 2 | 20.00% | 
| Sebastian Andrzej Siewior | 2 | 2.25% | 1 | 10.00% | 
| Javier Martinez Canillas | 2 | 2.25% | 1 | 10.00% | 
| Zebediah C. McClure | 1 | 1.12% | 1 | 10.00% | 
| Syed Mohammed Khasim | 1 | 1.12% | 1 | 10.00% | 
| Linus Walleij | 1 | 1.12% | 1 | 10.00% | 
| Total | 89 | 100.00% | 10 | 100.00% | 
static int omap_gpio_set_config(struct gpio_chip *chip, unsigned offset,
				unsigned long config)
{
	u32 debounce;
	if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
		return -ENOTSUPP;
	debounce = pinconf_to_config_argument(config);
	return omap_gpio_debounce(chip, offset, debounce);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Mika Westerberg | 51 | 100.00% | 1 | 100.00% | 
| Total | 51 | 100.00% | 1 | 100.00% | 
static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	struct gpio_bank *bank;
	unsigned long flags;
	bank = gpiochip_get_data(chip);
	raw_spin_lock_irqsave(&bank->lock, flags);
	bank->set_dataout(bank, offset, value);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 53 | 82.81% | 2 | 22.22% | 
| Syed Mohammed Khasim | 3 | 4.69% | 2 | 22.22% | 
| Kevin Hilman | 3 | 4.69% | 1 | 11.11% | 
| Sebastian Andrzej Siewior | 2 | 3.12% | 1 | 11.11% | 
| Tony Lindgren | 1 | 1.56% | 1 | 11.11% | 
| Javier Martinez Canillas | 1 | 1.56% | 1 | 11.11% | 
| Linus Walleij | 1 | 1.56% | 1 | 11.11% | 
| Total | 64 | 100.00% | 9 | 100.00% | 
/*---------------------------------------------------------------------*/
static void __init omap_gpio_show_rev(struct gpio_bank *bank)
{
	static bool called;
	u32 rev;
	if (called || bank->regs->revision == USHRT_MAX)
		return;
	rev = readw_relaxed(bank->base + bank->regs->revision);
	pr_info("OMAP GPIO hardware version %d.%d\n",
		(rev >> 4) & 0x0f, rev & 0x0f);
	called = true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 45 | 66.18% | 2 | 33.33% | 
| Kevin Hilman | 19 | 27.94% | 1 | 16.67% | 
| Santosh Shilimkar | 2 | 2.94% | 1 | 16.67% | 
| Tony Lindgren | 1 | 1.47% | 1 | 16.67% | 
| Victor Kamensky | 1 | 1.47% | 1 | 16.67% | 
| Total | 68 | 100.00% | 6 | 100.00% | 
static void omap_gpio_mod_init(struct gpio_bank *bank)
{
	void __iomem *base = bank->base;
	u32 l = 0xffffffff;
	if (bank->width == 16)
		l = 0xffff;
	if (bank->is_mpuio) {
		writel_relaxed(l, bank->base + bank->regs->irqenable);
		return;
	}
	omap_gpio_rmw(base, bank->regs->irqenable, l,
		      bank->regs->irqenable_inv);
	omap_gpio_rmw(base, bank->regs->irqstatus, l,
		      !bank->regs->irqenable_inv);
	if (bank->regs->debounce_en)
		writel_relaxed(0, base + bank->regs->debounce_en);
	/* Save OE default value (0xffffffff) in the context */
	bank->context.oe = readl_relaxed(bank->base + bank->regs->direction);
	 /* Initialize interface clk ungated, module enabled */
	if (bank->regs->ctrl)
		writel_relaxed(0, base + bank->regs->ctrl);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tarun Kanti DebBarma | 86 | 52.76% | 3 | 25.00% | 
| Varadarajan, Charulatha | 56 | 34.36% | 3 | 25.00% | 
| Tony Lindgren | 13 | 7.98% | 3 | 25.00% | 
| Victor Kamensky | 4 | 2.45% | 1 | 8.33% | 
| Syed Rafiuddin | 2 | 1.23% | 1 | 8.33% | 
| Javier Martinez Canillas | 2 | 1.23% | 1 | 8.33% | 
| Total | 163 | 100.00% | 12 | 100.00% | 
static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
{
	static int gpio;
	int irq_base = 0;
	int ret;
	/*
         * REVISIT eventually switch from OMAP-specific gpio structs
         * over to the generic ones
         */
	bank->chip.request = omap_gpio_request;
	bank->chip.free = omap_gpio_free;
	bank->chip.get_direction = omap_gpio_get_direction;
	bank->chip.direction_input = omap_gpio_input;
	bank->chip.get = omap_gpio_get;
	bank->chip.direction_output = omap_gpio_output;
	bank->chip.set_config = omap_gpio_set_config;
	bank->chip.set = omap_gpio_set;
	if (bank->is_mpuio) {
		bank->chip.label = "mpuio";
		if (bank->regs->wkup_en)
			bank->chip.parent = &omap_mpuio_device.dev;
		bank->chip.base = OMAP_MPUIO(0);
	} else {
		bank->chip.label = "gpio";
		bank->chip.base = gpio;
	}
	bank->chip.ngpio = bank->width;
	ret = gpiochip_add_data(&bank->chip, bank);
	if (ret) {
		dev_err(bank->chip.parent,
			"Could not register gpio chip %d\n", ret);
		return ret;
	}
	if (!bank->is_mpuio)
		gpio += bank->width;
#ifdef CONFIG_ARCH_OMAP1
	/*
         * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
         * irq_alloc_descs() since a base IRQ offset will no longer be needed.
         */
	irq_base = devm_irq_alloc_descs(bank->chip.parent,
					-1, 0, bank->width, 0);
	if (irq_base < 0) {
		dev_err(bank->chip.parent, "Couldn't allocate IRQ numbers\n");
		return -ENODEV;
	}
#endif
	/* MPUIO is a bit different, reading IRQ status clears it */
	if (bank->is_mpuio) {
		irqc->irq_ack = dummy_irq_chip.irq_ack;
		if (!bank->regs->wkup_en)
			irqc->irq_set_wake = NULL;
	}
	ret = gpiochip_irqchip_add(&bank->chip, irqc,
				   irq_base, handle_bad_irq,
				   IRQ_TYPE_NONE);
	if (ret) {
		dev_err(bank->chip.parent,
			"Couldn't add irqchip to gpiochip %d\n", ret);
		gpiochip_remove(&bank->chip);
		return -ENODEV;
	}
	gpiochip_set_chained_irqchip(&bank->chip, irqc, bank->irq, NULL);
	ret = devm_request_irq(bank->chip.parent, bank->irq,
			       omap_gpio_irq_handler,
			       0, dev_name(bank->chip.parent), bank);
	if (ret)
		gpiochip_remove(&bank->chip);
	return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Javier Martinez Canillas | 137 | 33.58% | 3 | 15.79% | 
| Varadarajan, Charulatha | 132 | 32.35% | 3 | 15.79% | 
| Grygorii Strashko | 53 | 12.99% | 2 | 10.53% | 
| Tony Lindgren | 45 | 11.03% | 2 | 10.53% | 
| Tarun Kanti DebBarma | 8 | 1.96% | 1 | 5.26% | 
| Nishanth Menon | 7 | 1.72% | 1 | 5.26% | 
| Yegor Yefremov | 7 | 1.72% | 1 | 5.26% | 
| Bartosz Golaszewski | 7 | 1.72% | 1 | 5.26% | 
| Linus Walleij | 4 | 0.98% | 2 | 10.53% | 
| Syed Rafiuddin | 3 | 0.74% | 1 | 5.26% | 
| Kevin Hilman | 3 | 0.74% | 1 | 5.26% | 
| Mika Westerberg | 2 | 0.49% | 1 | 5.26% | 
| Total | 408 | 100.00% | 19 | 100.00% | 
static const struct of_device_id omap_gpio_match[];
static int omap_gpio_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	const struct of_device_id *match;
	const struct omap_gpio_platform_data *pdata;
	struct resource *res;
	struct gpio_bank *bank;
	struct irq_chip *irqc;
	int ret;
	match = of_match_device(of_match_ptr(omap_gpio_match), dev);
	pdata = match ? match->data : dev_get_platdata(dev);
	if (!pdata)
		return -EINVAL;
	bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL);
	if (!bank) {
		dev_err(dev, "Memory alloc failed\n");
		return -ENOMEM;
	}
	irqc = devm_kzalloc(dev, sizeof(*irqc), GFP_KERNEL);
	if (!irqc)
		return -ENOMEM;
	irqc->irq_startup = omap_gpio_irq_startup,
	irqc->irq_shutdown = omap_gpio_irq_shutdown,
	irqc->irq_ack = omap_gpio_ack_irq,
	irqc->irq_mask = omap_gpio_mask_irq,
	irqc->irq_unmask = omap_gpio_unmask_irq,
	irqc->irq_set_type = omap_gpio_irq_type,
	irqc->irq_set_wake = omap_gpio_wake_enable,
	irqc->irq_bus_lock = omap_gpio_irq_bus_lock,
	irqc->irq_bus_sync_unlock = gpio_irq_bus_sync_unlock,
	irqc->name = dev_name(&pdev->dev);
	irqc->flags = IRQCHIP_MASK_ON_SUSPEND;
	bank->irq = platform_get_irq(pdev, 0);
	if (bank->irq <= 0) {
		if (!bank->irq)
			bank->irq = -ENXIO;
		if (bank->irq != -EPROBE_DEFER)
			dev_err(dev,
				"can't get irq resource ret=%d\n", bank->irq);
		return bank->irq;
	}
	bank->chip.parent = dev;
	bank->chip.owner = THIS_MODULE;
	bank->dbck_flag = pdata->dbck_flag;
	bank->stride = pdata->bank_stride;
	bank->width = pdata->bank_width;
	bank->is_mpuio = pdata->is_mpuio;
	bank->non_wakeup_gpios = pdata->non_wakeup_gpios;
	bank->regs = pdata->regs;
#ifdef CONFIG_OF_GPIO
	bank->chip.of_node = of_node_get(node);
#endif
	if (node) {
		if (!of_property_read_bool(node, "ti,gpio-always-on"))
			bank->loses_context = true;
	} else {
		bank->loses_context = pdata->loses_context;
		if (bank->loses_context)
			bank->get_context_loss_count =
				pdata->get_context_loss_count;
	}
	if (bank->regs->set_dataout && bank->regs->clr_dataout)
		bank->set_dataout = omap_set_gpio_dataout_reg;
	else
		bank->set_dataout = omap_set_gpio_dataout_mask;
	raw_spin_lock_init(&bank->lock);
	raw_spin_lock_init(&bank->wa_lock);
	/* Static mapping, never released */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	bank->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(bank->base)) {
		return PTR_ERR(bank->base);
	}
	if (bank->dbck_flag) {
		bank->dbck = devm_clk_get(dev, "dbclk");
		if (IS_ERR(bank->dbck)) {
			dev_err(dev,
				"Could not get gpio dbck. Disable debounce\n");
			bank->dbck_flag = false;
		} else {
			clk_prepare(bank->dbck);
		}
	}
	platform_set_drvdata(pdev, bank);
	pm_runtime_enable(dev);
	pm_runtime_irq_safe(dev);
	pm_runtime_get_sync(dev);
	if (bank->is_mpuio)
		omap_mpuio_init(bank);
	omap_gpio_mod_init(bank);
	ret = omap_gpio_chip_init(bank, irqc);
	if (ret) {
		pm_runtime_put_sync(dev);
		pm_runtime_disable(dev);
		return ret;
	}
	omap_gpio_show_rev(bank);
	pm_runtime_put(dev);
	list_add_tail(&bank->node, &omap_gpio_list);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 146 | 22.88% | 5 | 11.36% | 
| Grygorii Strashko | 126 | 19.75% | 6 | 13.64% | 
| Benoît Cousson | 88 | 13.79% | 3 | 6.82% | 
| Nishanth Menon | 79 | 12.38% | 1 | 2.27% | 
| Jon Hunter | 39 | 6.11% | 3 | 6.82% | 
| Tony Lindgren | 36 | 5.64% | 6 | 13.64% | 
| Kevin Hilman | 36 | 5.64% | 2 | 4.55% | 
| Tarun Kanti DebBarma | 25 | 3.92% | 3 | 6.82% | 
| Javier Martinez Canillas | 22 | 3.45% | 4 | 9.09% | 
| David Brownell | 14 | 2.19% | 5 | 11.36% | 
| Jingoo Han | 13 | 2.04% | 2 | 4.55% | 
| Jouni Högander | 11 | 1.72% | 1 | 2.27% | 
| Sebastian Andrzej Siewior | 1 | 0.16% | 1 | 2.27% | 
| Linus Walleij | 1 | 0.16% | 1 | 2.27% | 
| Uwe Kleine-König | 1 | 0.16% | 1 | 2.27% | 
| Total | 638 | 100.00% | 44 | 100.00% | 
static int omap_gpio_remove(struct platform_device *pdev)
{
	struct gpio_bank *bank = platform_get_drvdata(pdev);
	list_del(&bank->node);
	gpiochip_remove(&bank->chip);
	pm_runtime_disable(&pdev->dev);
	if (bank->dbck_flag)
		clk_unprepare(bank->dbck);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tony Lindgren | 46 | 75.41% | 1 | 33.33% | 
| Grygorii Strashko | 15 | 24.59% | 2 | 66.67% | 
| Total | 61 | 100.00% | 3 | 100.00% | 
#ifdef CONFIG_ARCH_OMAP2PLUS
#if defined(CONFIG_PM)
static void omap_gpio_restore_context(struct gpio_bank *bank);
static int omap_gpio_runtime_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct gpio_bank *bank = platform_get_drvdata(pdev);
	u32 l1 = 0, l2 = 0;
	unsigned long flags;
	u32 wake_low, wake_hi;
	raw_spin_lock_irqsave(&bank->lock, flags);
	/*
         * Only edges can generate a wakeup event to the PRCM.
         *
         * Therefore, ensure any wake-up capable GPIOs have
         * edge-detection enabled before going idle to ensure a wakeup
         * to the PRCM is generated on a GPIO transition. (c.f. 34xx
         * NDA TRM 25.5.3.1)
         *
         * The normal values will be restored upon ->runtime_resume()
         * by writing back the values saved in bank->context.
         */
	wake_low = bank->context.leveldetect0 & bank->context.wake_en;
	if (wake_low)
		writel_relaxed(wake_low | bank->context.fallingdetect,
			     bank->base + bank->regs->fallingdetect);
	wake_hi = bank->context.leveldetect1 & bank->context.wake_en;
	if (wake_hi)
		writel_relaxed(wake_hi | bank->context.risingdetect,
			     bank->base + bank->regs->risingdetect);
	if (!bank->enabled_non_wakeup_gpios)
		goto update_gpio_context_count;
	if (bank->power_mode != OFF_MODE) {
		bank->power_mode = 0;
		goto update_gpio_context_count;
	}
	/*
         * If going to OFF, remove triggering for all
         * non-wakeup GPIOs.  Otherwise spurious IRQs will be
         * generated.  See OMAP2420 Errata item 1.101.
         */
	bank->saved_datain = readl_relaxed(bank->base +
						bank->regs->datain);
	l1 = bank->context.fallingdetect;
	l2 = bank->context.risingdetect;
	l1 &= ~bank->enabled_non_wakeup_gpios;
	l2 &= ~bank->enabled_non_wakeup_gpios;
	writel_relaxed(l1, bank->base + bank->regs->fallingdetect);
	writel_relaxed(l2, bank->base + bank->regs->risingdetect);
	bank->workaround_enabled = true;
update_gpio_context_count:
	if (bank->get_context_loss_count)
		bank->context_loss_count =
				bank->get_context_loss_count(dev);
	omap_gpio_dbck_disable(bank);
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Kevin Hilman | 102 | 35.42% | 5 | 26.32% | 
| Tarun Kanti DebBarma | 100 | 34.72% | 7 | 36.84% | 
| Juha Yrjölä | 54 | 18.75% | 1 | 5.26% | 
| Syed Rafiuddin | 18 | 6.25% | 1 | 5.26% | 
| Victor Kamensky | 5 | 1.74% | 1 | 5.26% | 
| Sanjeev Premi | 4 | 1.39% | 1 | 5.26% | 
| Varadarajan, Charulatha | 2 | 0.69% | 1 | 5.26% | 
| Sebastian Andrzej Siewior | 2 | 0.69% | 1 | 5.26% | 
| Javier Martinez Canillas | 1 | 0.35% | 1 | 5.26% | 
| Total | 288 | 100.00% | 19 | 100.00% | 
static void omap_gpio_init_context(struct gpio_bank *p);
static int omap_gpio_runtime_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct gpio_bank *bank = platform_get_drvdata(pdev);
	u32 l = 0, gen, gen0, gen1;
	unsigned long flags;
	int c;
	raw_spin_lock_irqsave(&bank->lock, flags);
	/*
         * On the first resume during the probe, the context has not
         * been initialised and so initialise it now. Also initialise
         * the context loss count.
         */
	if (bank->loses_context && !bank->context_valid) {
		omap_gpio_init_context(bank);
		if (bank->get_context_loss_count)
			bank->context_loss_count =
				bank->get_context_loss_count(dev);
	}
	omap_gpio_dbck_enable(bank);
	/*
         * In ->runtime_suspend(), level-triggered, wakeup-enabled
         * GPIOs were set to edge trigger also in order to be able to
         * generate a PRCM wakeup.  Here we restore the
         * pre-runtime_suspend() values for edge triggering.
         */
	writel_relaxed(bank->context.fallingdetect,
		     bank->base + bank->regs->fallingdetect);
	writel_relaxed(bank->context.risingdetect,
		     bank->base + bank->regs->risingdetect);
	if (bank->loses_context) {
		if (!bank->get_context_loss_count) {
			omap_gpio_restore_context(bank);
		} else {
			c = bank->get_context_loss_count(dev);
			if (c != bank->context_loss_count) {
				omap_gpio_restore_context(bank);
			} else {
				raw_spin_unlock_irqrestore(&bank->lock, flags);
				return 0;
			}
		}
	}
	if (!bank->workaround_enabled) {
		raw_spin_unlock_irqrestore(&bank->lock, flags);
		return 0;
	}
	l = readl_relaxed(bank->base + bank->regs->datain);
	/*
         * 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 ^= bank->saved_datain;
	l &= bank->enabled_non_wakeup_gpios;
	/*
         * No need to generate IRQs for the rising edge for gpio IRQs
         * configured with falling edge only; and vice versa.
         */
	gen0 = l & bank->context.fallingdetect;
	gen0 &= bank->saved_datain;
	gen1 = l & bank->context.risingdetect;
	gen1 &= ~(bank->saved_datain);
	/* FIXME: Consider GPIO IRQs with level detections properly! */
	gen = l & (~(bank->context.fallingdetect) &
					 ~(bank->context.risingdetect));
	/* Consider all GPIO IRQs needed to be updated */
	gen |= gen0 | gen1;
	if (gen) {
		u32 old0, old1;
		old0 = readl_relaxed(bank->base + bank->regs->leveldetect0);
		old1 = readl_relaxed(bank->base + bank->regs->leveldetect1);
		if (!bank->regs->irqstatus_raw0) {
			writel_relaxed(old0 | gen, bank->base +
						bank->regs->leveldetect0);
			writel_relaxed(old1 | gen, bank->base +
						bank->regs->leveldetect1);
		}
		if (bank->regs->irqstatus_raw0) {
			writel_relaxed(old0 | l, bank->base +
						bank->regs->leveldetect0);
			writel_relaxed(old1 | l, bank->base +
						bank->regs->leveldetect1);
		}
		writel_relaxed(old0, bank->base + bank->regs->leveldetect0);
		writel_relaxed(old1, bank->base + bank->regs->leveldetect1);
	}
	bank->workaround_enabled = false;
	raw_spin_unlock_irqrestore(&bank->lock, flags);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tarun Kanti DebBarma | 215 | 42.91% | 7 | 30.43% | 
| Juha Yrjölä | 68 | 13.57% | 1 | 4.35% | 
| Eero Nurkkala | 62 | 12.38% | 1 | 4.35% | 
| Jon Hunter | 58 | 11.58% | 2 | 8.70% | 
| Kevin Hilman | 46 | 9.18% | 4 | 17.39% | 
| Syed Rafiuddin | 25 | 4.99% | 1 | 4.35% | 
| Victor Kamensky | 11 | 2.20% | 1 | 4.35% | 
| Tony Lindgren | 6 | 1.20% | 1 | 4.35% | 
| Sebastian Andrzej Siewior | 4 | 0.80% | 1 | 4.35% | 
| Sanjeev Premi | 2 | 0.40% | 1 | 4.35% | 
| Varadarajan, Charulatha | 2 | 0.40% | 1 | 4.35% | 
| Tero Kristo | 1 | 0.20% | 1 | 4.35% | 
| Javier Martinez Canillas | 1 | 0.20% | 1 | 4.35% | 
| Total | 501 | 100.00% | 23 | 100.00% | 
#endif /* CONFIG_PM */
#if IS_BUILTIN(CONFIG_GPIO_OMAP)
void omap2_gpio_prepare_for_idle(int pwr_mode)
{
	struct gpio_bank *bank;
	list_for_each_entry(bank, &omap_gpio_list, node) {
		if (!BANK_USED(bank) || !bank->loses_context)
			continue;
		bank->power_mode = pwr_mode;
		pm_runtime_put_sync_suspend(bank->chip.parent);
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tarun Kanti DebBarma | 44 | 84.62% | 1 | 25.00% | 
| Javier Martinez Canillas | 3 | 5.77% | 1 | 25.00% | 
| Grygorii Strashko | 3 | 5.77% | 1 | 25.00% | 
| Juha Yrjölä | 2 | 3.85% | 1 | 25.00% | 
| Total | 52 | 100.00% | 4 | 100.00% | 
void omap2_gpio_resume_after_idle(void)
{
	struct gpio_bank *bank;
	list_for_each_entry(bank, &omap_gpio_list, node) {
		if (!BANK_USED(bank) || !bank->loses_context)
			continue;
		pm_runtime_get_sync(bank->chip.parent);
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tarun Kanti DebBarma | 39 | 86.67% | 1 | 33.33% | 
| Grygorii Strashko | 3 | 6.67% | 1 | 33.33% | 
| Javier Martinez Canillas | 3 | 6.67% | 1 | 33.33% | 
| Total | 45 | 100.00% | 3 | 100.00% | 
#endif
#if defined(CONFIG_PM)
static void omap_gpio_init_context(struct gpio_bank *p)
{
	struct omap_gpio_reg_offs *regs = p->regs;
	void __iomem *base = p->base;
	p->context.ctrl		= readl_relaxed(base + regs->ctrl);
	p->context.oe		= readl_relaxed(base + regs->direction);
	p->context.wake_en	= readl_relaxed(base + regs->wkup_en);
	p->context.leveldetect0	= readl_relaxed(base + regs->leveldetect0);
	p->context.leveldetect1	= readl_relaxed(base + regs->leveldetect1);
	p->context.risingdetect	= readl_relaxed(base + regs->risingdetect);
	p->context.fallingdetect = readl_relaxed(base + regs->fallingdetect);
	p->context.irqenable1	= readl_relaxed(base + regs->irqenable);
	p->context.irqenable2	= readl_relaxed(base + regs->irqenable2);
	if (regs->set_dataout && p->regs->clr_dataout)
		p->context.dataout = readl_relaxed(base + regs->set_dataout);
	else
		p->context.dataout = readl_relaxed(base + regs->dataout);
	p->context_valid = true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Jon Hunter | 202 | 94.84% | 1 | 50.00% | 
| Victor Kamensky | 11 | 5.16% | 1 | 50.00% | 
| Total | 213 | 100.00% | 2 | 100.00% | 
static void omap_gpio_restore_context(struct gpio_bank *bank)
{
	writel_relaxed(bank->context.wake_en,
				bank->base + bank->regs->wkup_en);
	writel_relaxed(bank->context.ctrl, bank->base + bank->regs->ctrl);
	writel_relaxed(bank->context.leveldetect0,
				bank->base + bank->regs->leveldetect0);
	writel_relaxed(bank->context.leveldetect1,
				bank->base + bank->regs->leveldetect1);
	writel_relaxed(bank->context.risingdetect,
				bank->base + bank->regs->risingdetect);
	writel_relaxed(bank->context.fallingdetect,
				bank->base + bank->regs->fallingdetect);
	if (bank->regs->set_dataout && bank->regs->clr_dataout)
		writel_relaxed(bank->context.dataout,
				bank->base + bank->regs->set_dataout);
	else
		writel_relaxed(bank->context.dataout,
				bank->base + bank->regs->dataout);
	writel_relaxed(bank->context.oe, bank->base + bank->regs->direction);
	if (bank->dbck_enable_mask) {
		writel_relaxed(bank->context.debounce, bank->base +
					bank->regs->debounce);
		writel_relaxed(bank->context.debounce_en,
					bank->base + bank->regs->debounce_en);
	}
	writel_relaxed(bank->context.irqenable1,
				bank->base + bank->regs->irqenable);
	writel_relaxed(bank->context.irqenable2,
				bank->base + bank->regs->irqenable2);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Nishanth Menon | 98 | 34.88% | 4 | 40.00% | 
| Rajendra Nayak | 97 | 34.52% | 1 | 10.00% | 
| Tarun Kanti DebBarma | 42 | 14.95% | 2 | 20.00% | 
| Varadarajan, Charulatha | 31 | 11.03% | 2 | 20.00% | 
| Victor Kamensky | 13 | 4.63% | 1 | 10.00% | 
| Total | 281 | 100.00% | 10 | 100.00% | 
#endif /* CONFIG_PM */
#else
#define omap_gpio_runtime_suspend NULL
#define omap_gpio_runtime_resume NULL
static inline void omap_gpio_init_context(struct gpio_bank *p) {}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Jon Hunter | 10 | 90.91% | 1 | 50.00% | 
| Arnd Bergmann | 1 | 9.09% | 1 | 50.00% | 
| Total | 11 | 100.00% | 2 | 100.00% | 
#endif
static const struct dev_pm_ops gpio_pm_ops = {
	SET_RUNTIME_PM_OPS(omap_gpio_runtime_suspend, omap_gpio_runtime_resume,
									NULL)
};
#if defined(CONFIG_OF)
static struct omap_gpio_reg_offs omap2_gpio_regs = {
	.revision =		OMAP24XX_GPIO_REVISION,
	.direction =		OMAP24XX_GPIO_OE,
	.datain =		OMAP24XX_GPIO_DATAIN,
	.dataout =		OMAP24XX_GPIO_DATAOUT,
	.set_dataout =		OMAP24XX_GPIO_SETDATAOUT,
	.clr_dataout =		OMAP24XX_GPIO_CLEARDATAOUT,
	.irqstatus =		OMAP24XX_GPIO_IRQSTATUS1,
	.irqstatus2 =		OMAP24XX_GPIO_IRQSTATUS2,
	.irqenable =		OMAP24XX_GPIO_IRQENABLE1,
	.irqenable2 =		OMAP24XX_GPIO_IRQENABLE2,
	.set_irqenable =	OMAP24XX_GPIO_SETIRQENABLE1,
	.clr_irqenable =	OMAP24XX_GPIO_CLEARIRQENABLE1,
	.debounce =		OMAP24XX_GPIO_DEBOUNCE_VAL,
	.debounce_en =		OMAP24XX_GPIO_DEBOUNCE_EN,
	.ctrl =			OMAP24XX_GPIO_CTRL,
	.wkup_en =		OMAP24XX_GPIO_WAKE_EN,
	.leveldetect0 =		OMAP24XX_GPIO_LEVELDETECT0,
	.leveldetect1 =		OMAP24XX_GPIO_LEVELDETECT1,
	.risingdetect =		OMAP24XX_GPIO_RISINGDETECT,
	.fallingdetect =	OMAP24XX_GPIO_FALLINGDETECT,
};
static struct omap_gpio_reg_offs omap4_gpio_regs = {
	.revision =		OMAP4_GPIO_REVISION,
	.direction =		OMAP4_GPIO_OE,
	.datain =		OMAP4_GPIO_DATAIN,
	.dataout =		OMAP4_GPIO_DATAOUT,
	.set_dataout =		OMAP4_GPIO_SETDATAOUT,
	.clr_dataout =		OMAP4_GPIO_CLEARDATAOUT,
	.irqstatus =		OMAP4_GPIO_IRQSTATUS0,
	.irqstatus2 =		OMAP4_GPIO_IRQSTATUS1,
	.irqenable =		OMAP4_GPIO_IRQSTATUSSET0,
	.irqenable2 =		OMAP4_GPIO_IRQSTATUSSET1,
	.set_irqenable =	OMAP4_GPIO_IRQSTATUSSET0,
	.clr_irqenable =	OMAP4_GPIO_IRQSTATUSCLR0,
	.debounce =		OMAP4_GPIO_DEBOUNCINGTIME,
	.debounce_en =		OMAP4_GPIO_DEBOUNCENABLE,
	.ctrl =			OMAP4_GPIO_CTRL,
	.wkup_en =		OMAP4_GPIO_IRQWAKEN0,
	.leveldetect0 =		OMAP4_GPIO_LEVELDETECT0,
	.leveldetect1 =		OMAP4_GPIO_LEVELDETECT1,
	.risingdetect =		OMAP4_GPIO_RISINGDETECT,
	.fallingdetect =	OMAP4_GPIO_FALLINGDETECT,
};
static const struct omap_gpio_platform_data omap2_pdata = {
	.regs = &omap2_gpio_regs,
	.bank_width = 32,
	.dbck_flag = false,
};
static const struct omap_gpio_platform_data omap3_pdata = {
	.regs = &omap2_gpio_regs,
	.bank_width = 32,
	.dbck_flag = true,
};
static const struct omap_gpio_platform_data omap4_pdata = {
	.regs = &omap4_gpio_regs,
	.bank_width = 32,
	.dbck_flag = true,
};
static const struct of_device_id omap_gpio_match[] = {
	{
		.compatible = "ti,omap4-gpio",
		.data = &omap4_pdata,
        },
	{
		.compatible = "ti,omap3-gpio",
		.data = &omap3_pdata,
        },
	{
		.compatible = "ti,omap2-gpio",
		.data = &omap2_pdata,
        },
	{ },
};
MODULE_DEVICE_TABLE(of, omap_gpio_match);
#endif
static struct platform_driver omap_gpio_driver = {
	.probe		= omap_gpio_probe,
	.remove		= omap_gpio_remove,
	.driver		= {
		.name	= "omap_gpio",
		.pm	= &gpio_pm_ops,
		.of_match_table = of_match_ptr(omap_gpio_match),
        },
};
/*
 * gpio driver register needs to be done before
 * machine_init functions access gpio APIs.
 * Hence omap_gpio_drv_reg() is a postcore_initcall.
 */
static int __init omap_gpio_drv_reg(void)
{
	return platform_driver_register(&omap_gpio_driver);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tony Lindgren | 8 | 50.00% | 1 | 33.33% | 
| Varadarajan, Charulatha | 7 | 43.75% | 1 | 33.33% | 
| David Brownell | 1 | 6.25% | 1 | 33.33% | 
| Total | 16 | 100.00% | 3 | 100.00% | 
postcore_initcall(omap_gpio_drv_reg);
static void __exit omap_gpio_exit(void)
{
	platform_driver_unregister(&omap_gpio_driver);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Tony Lindgren | 15 | 100.00% | 1 | 100.00% | 
| Total | 15 | 100.00% | 1 | 100.00% | 
module_exit(omap_gpio_exit);
MODULE_DESCRIPTION("omap gpio driver");
MODULE_ALIAS("platform:gpio-omap");
MODULE_LICENSE("GPL v2");
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Varadarajan, Charulatha | 1781 | 22.50% | 11 | 6.51% | 
| Tarun Kanti DebBarma | 1132 | 14.30% | 23 | 13.61% | 
| Javier Martinez Canillas | 727 | 9.19% | 8 | 4.73% | 
| Tony Lindgren | 696 | 8.79% | 14 | 8.28% | 
| Grygorii Strashko | 607 | 7.67% | 21 | 12.43% | 
| Kevin Hilman | 492 | 6.22% | 18 | 10.65% | 
| Benoît Cousson | 482 | 6.09% | 4 | 2.37% | 
| Jon Hunter | 478 | 6.04% | 7 | 4.14% | 
| Nishanth Menon | 214 | 2.70% | 5 | 2.96% | 
| David Brownell | 168 | 2.12% | 11 | 6.51% | 
| Juha Yrjölä | 163 | 2.06% | 1 | 0.59% | 
| Rajendra Nayak | 99 | 1.25% | 1 | 0.59% | 
| Yegor Yefremov | 95 | 1.20% | 1 | 0.59% | 
| Victor Kamensky | 94 | 1.19% | 1 | 0.59% | 
| Colin Cross | 70 | 0.88% | 2 | 1.18% | 
| Eero Nurkkala | 62 | 0.78% | 1 | 0.59% | 
| Syed Rafiuddin | 60 | 0.76% | 1 | 0.59% | 
| Cory Maccarrone | 54 | 0.68% | 1 | 0.59% | 
| Mika Westerberg | 53 | 0.67% | 1 | 0.59% | 
| Imre Deak | 47 | 0.59% | 2 | 1.18% | 
| David Rivshin | 46 | 0.58% | 1 | 0.59% | 
| Felipe Balbi | 45 | 0.57% | 1 | 0.59% | 
| Sebastian Andrzej Siewior | 38 | 0.48% | 1 | 0.59% | 
| Syed Mohammed Khasim | 34 | 0.43% | 2 | 1.18% | 
| Lennert Buytenhek | 31 | 0.39% | 1 | 0.59% | 
| Grazvydas Ignotas | 31 | 0.39% | 1 | 0.59% | 
| Roger Quadros | 19 | 0.24% | 2 | 1.18% | 
| Jouni Högander | 16 | 0.20% | 1 | 0.59% | 
| Linus Walleij | 14 | 0.18% | 2 | 1.18% | 
| Jingoo Han | 13 | 0.16% | 2 | 1.18% | 
| Bartosz Golaszewski | 7 | 0.09% | 1 | 0.59% | 
| Sanjeev Premi | 6 | 0.08% | 1 | 0.59% | 
| Rafael J. Wysocki | 6 | 0.08% | 2 | 1.18% | 
| Thomas Gleixner | 5 | 0.06% | 2 | 1.18% | 
| Alistair Buxton | 4 | 0.05% | 1 | 0.59% | 
| Santosh Shilimkar | 4 | 0.05% | 1 | 0.59% | 
| Zebediah C. McClure | 3 | 0.04% | 1 | 0.59% | 
| Will Deacon | 3 | 0.04% | 1 | 0.59% | 
| Chen Gang S | 3 | 0.04% | 1 | 0.59% | 
| Jarkko Nikula | 3 | 0.04% | 1 | 0.59% | 
| Catalin Marinas | 2 | 0.03% | 1 | 0.59% | 
| Russell King | 2 | 0.03% | 2 | 1.18% | 
| Tero Kristo | 1 | 0.01% | 1 | 0.59% | 
| Uwe Kleine-König | 1 | 0.01% | 1 | 0.59% | 
| Hiroshi Doyu | 1 | 0.01% | 1 | 0.59% | 
| Janusz Krzysztofik | 1 | 0.01% | 1 | 0.59% | 
| Axel Lin | 1 | 0.01% | 1 | 0.59% | 
| Arnd Bergmann | 1 | 0.01% | 1 | 0.59% | 
| Total | 7915 | 100.00% | 169 | 100.00% | 
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.