[v2,15/16] gpio: tegra: Use banked GPIO infrastructure

Message ID 20170928095628.21966-16-thierry.reding@gmail.com
State Superseded
Headers show
Series
  • gpio: Tight IRQ chip integration and banked infrastructure
Related show

Commit Message

Thierry Reding Sept. 28, 2017, 9:56 a.m.
From: Thierry Reding <treding@nvidia.com>

Convert the Tegra GPIO driver to use the banked GPIO infrastructure,
which simplifies some parts of the driver.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpio/Kconfig      |   1 +
 drivers/gpio/gpio-tegra.c | 203 ++++++++++++++++++++++------------------------
 2 files changed, 98 insertions(+), 106 deletions(-)

Comments

Grygorii Strashko Oct. 9, 2017, 9:22 p.m. | #1
On 09/28/2017 04:56 AM, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> Convert the Tegra GPIO driver to use the banked GPIO infrastructure,
> which simplifies some parts of the driver.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>   drivers/gpio/Kconfig      |   1 +
>   drivers/gpio/gpio-tegra.c | 203 ++++++++++++++++++++++------------------------
>   2 files changed, 98 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index db3e446ad9b3..458157d6d491 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -439,6 +439,7 @@ config GPIO_TEGRA
>   	default ARCH_TEGRA
>   	depends on ARCH_TEGRA || COMPILE_TEST

... 

> @@ -616,76 +617,66 @@ static int tegra_gpio_probe(struct platform_device *pdev)
>   	tgi->ic.irq_set_wake		= tegra_gpio_irq_set_wake;
>   #endif
>   
> +	irq = &tgi->gc.irq;
> +	irq->chip = &tgi->ic;
> +	irq->handler = handle_simple_irq;
> +	irq->lock_key = &tegra_gpio_lock_class;

As per current gpiolib design lockdep lock_class_key is assigned 
automatically and hidden from gpiolib users. 
Why do you need to do the same manually?

> +	irq->default_type = IRQ_TYPE_NONE;
> +	irq->parent_handler = gpio_irq_chip_banked_chained_handler;
> +	irq->update_bank = tegra_gpio_update_bank;
> +
> +	irq->parents = devm_kcalloc(&pdev->dev, tgi->gc.num_banks,
> +				    sizeof(unsigned int), GFP_KERNEL);
> +	if (!irq->parents)
> +		return -ENOMEM;
> +

...

>   
>   	tegra_gpio_debuginit(tgi);
>   
>
Thierry Reding Oct. 10, 2017, 10:27 a.m. | #2
On Mon, Oct 09, 2017 at 04:22:29PM -0500, Grygorii Strashko wrote:
> 
> 
> On 09/28/2017 04:56 AM, Thierry Reding wrote:
> > From: Thierry Reding <treding@nvidia.com>
> > 
> > Convert the Tegra GPIO driver to use the banked GPIO infrastructure,
> > which simplifies some parts of the driver.
> > 
> > Signed-off-by: Thierry Reding <treding@nvidia.com>
> > ---
> >   drivers/gpio/Kconfig      |   1 +
> >   drivers/gpio/gpio-tegra.c | 203 ++++++++++++++++++++++------------------------
> >   2 files changed, 98 insertions(+), 106 deletions(-)
> > 
> > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> > index db3e446ad9b3..458157d6d491 100644
> > --- a/drivers/gpio/Kconfig
> > +++ b/drivers/gpio/Kconfig
> > @@ -439,6 +439,7 @@ config GPIO_TEGRA
> >   	default ARCH_TEGRA
> >   	depends on ARCH_TEGRA || COMPILE_TEST
> 
> ... 
> 
> > @@ -616,76 +617,66 @@ static int tegra_gpio_probe(struct platform_device *pdev)
> >   	tgi->ic.irq_set_wake		= tegra_gpio_irq_set_wake;
> >   #endif
> >   
> > +	irq = &tgi->gc.irq;
> > +	irq->chip = &tgi->ic;
> > +	irq->handler = handle_simple_irq;
> > +	irq->lock_key = &tegra_gpio_lock_class;
> 
> As per current gpiolib design lockdep lock_class_key is assigned 
> automatically and hidden from gpiolib users. 
> Why do you need to do the same manually?

Can you elaborate? I don't see the lock class key getting set anywhere.
gpiolib does set if for interrupts, but only if the drivers assigned it
before adding the chip.

Thierry
Grygorii Strashko Oct. 10, 2017, 7:31 p.m. | #3
On 10/10/2017 05:27 AM, Thierry Reding wrote:
> On Mon, Oct 09, 2017 at 04:22:29PM -0500, Grygorii Strashko wrote:
>>
>>
>> On 09/28/2017 04:56 AM, Thierry Reding wrote:
>>> From: Thierry Reding <treding@nvidia.com>
>>>
>>> Convert the Tegra GPIO driver to use the banked GPIO infrastructure,
>>> which simplifies some parts of the driver.
>>>
>>> Signed-off-by: Thierry Reding <treding@nvidia.com>
>>> ---
>>>    drivers/gpio/Kconfig      |   1 +
>>>    drivers/gpio/gpio-tegra.c | 203 ++++++++++++++++++++++------------------------
>>>    2 files changed, 98 insertions(+), 106 deletions(-)
>>>
>>> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
>>> index db3e446ad9b3..458157d6d491 100644
>>> --- a/drivers/gpio/Kconfig
>>> +++ b/drivers/gpio/Kconfig
>>> @@ -439,6 +439,7 @@ config GPIO_TEGRA
>>>    	default ARCH_TEGRA
>>>    	depends on ARCH_TEGRA || COMPILE_TEST
>>
>> ...
>>
>>> @@ -616,76 +617,66 @@ static int tegra_gpio_probe(struct platform_device *pdev)
>>>    	tgi->ic.irq_set_wake		= tegra_gpio_irq_set_wake;
>>>    #endif
>>>    
>>> +	irq = &tgi->gc.irq;
>>> +	irq->chip = &tgi->ic;
>>> +	irq->handler = handle_simple_irq;
>>> +	irq->lock_key = &tegra_gpio_lock_class;
>>
>> As per current gpiolib design lockdep lock_class_key is assigned
>> automatically and hidden from gpiolib users.
>> Why do you need to do the same manually?
> 
> Can you elaborate? I don't see the lock class key getting set anywhere.
> gpiolib does set if for interrupts, but only if the drivers assigned it
> before adding the chip.
> 

include/linux/gpio/driver.h

#ifdef CONFIG_LOCKDEP

/*
 * Lockdep requires that each irqchip instance be created with a
 * unique key so as to avoid unnecessary warnings. This upfront
 * boilerplate static inlines provides such a key for each
 * unique instance.
 */
static inline int gpiochip_irqchip_add(struct gpio_chip *gpiochip,
				       struct irq_chip *irqchip,
				       unsigned int first_irq,
				       irq_flow_handler_t handler,
				       unsigned int type)
{
	static struct lock_class_key key;
^^^

	return gpiochip_irqchip_add_key(gpiochip, irqchip, first_irq,
					handler, type, false, &key);
}

Patch

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index db3e446ad9b3..458157d6d491 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -439,6 +439,7 @@  config GPIO_TEGRA
 	default ARCH_TEGRA
 	depends on ARCH_TEGRA || COMPILE_TEST
 	depends on OF_GPIO
+	select GPIOLIB_IRQCHIP
 	help
 	  Say yes here to support GPIO pins on NVIDIA Tegra SoCs.
 
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index fbaf974277df..bfa0abec743b 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -67,8 +67,8 @@ 
 struct tegra_gpio_info;
 
 struct tegra_gpio_bank {
-	unsigned int bank;
-	unsigned int irq;
+	struct gpio_bank bank;
+	unsigned int index;
 	spinlock_t lvl_lock[4];
 	spinlock_t dbc_lock[4];	/* Lock for updating debounce count register */
 #ifdef CONFIG_PM_SLEEP
@@ -84,6 +84,11 @@  struct tegra_gpio_bank {
 	struct tegra_gpio_info *tgi;
 };
 
+static struct tegra_gpio_bank *to_tegra_gpio_bank(struct gpio_bank *bank)
+{
+	return container_of(bank, struct tegra_gpio_bank, bank);
+}
+
 struct tegra_gpio_soc_config {
 	bool debounce_supported;
 	u32 bank_stride;
@@ -98,9 +103,14 @@  struct tegra_gpio_info {
 	const struct tegra_gpio_soc_config	*soc;
 	struct gpio_chip			gc;
 	struct irq_chip				ic;
-	u32					bank_count;
 };
 
+static inline struct tegra_gpio_info *
+to_tegra_gpio_info(struct gpio_chip *chip)
+{
+	return container_of(chip, struct tegra_gpio_info, gc);
+}
+
 static inline void tegra_gpio_writel(struct tegra_gpio_info *tgi,
 				     u32 val, u32 reg)
 {
@@ -264,8 +274,8 @@  static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
 
 static void tegra_gpio_irq_ack(struct irq_data *d)
 {
-	struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	struct tegra_gpio_info *tgi = bank->tgi;
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct tegra_gpio_info *tgi = to_tegra_gpio_info(chip);
 	unsigned int gpio = d->hwirq;
 
 	tegra_gpio_writel(tgi, 1 << GPIO_BIT(gpio), GPIO_INT_CLR(tgi, gpio));
@@ -273,8 +283,8 @@  static void tegra_gpio_irq_ack(struct irq_data *d)
 
 static void tegra_gpio_irq_mask(struct irq_data *d)
 {
-	struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	struct tegra_gpio_info *tgi = bank->tgi;
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct tegra_gpio_info *tgi = to_tegra_gpio_info(chip);
 	unsigned int gpio = d->hwirq;
 
 	tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 0);
@@ -282,8 +292,8 @@  static void tegra_gpio_irq_mask(struct irq_data *d)
 
 static void tegra_gpio_irq_unmask(struct irq_data *d)
 {
-	struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	struct tegra_gpio_info *tgi = bank->tgi;
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct tegra_gpio_info *tgi = to_tegra_gpio_info(chip);
 	unsigned int gpio = d->hwirq;
 
 	tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 1);
@@ -292,12 +302,15 @@  static void tegra_gpio_irq_unmask(struct irq_data *d)
 static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 {
 	unsigned int gpio = d->hwirq, port = GPIO_PORT(gpio), lvl_type;
-	struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	struct tegra_gpio_info *tgi = bank->tgi;
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct tegra_gpio_info *tgi = to_tegra_gpio_info(chip);
+	struct tegra_gpio_bank *bank;
 	unsigned long flags;
 	u32 val;
 	int ret;
 
+	bank = &tgi->bank_info[GPIO_BANK(gpio)];
+
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_RISING:
 		lvl_type = GPIO_INT_LVL_EDGE_RISING;
@@ -352,52 +365,27 @@  static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 
 static void tegra_gpio_irq_shutdown(struct irq_data *d)
 {
-	struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	struct tegra_gpio_info *tgi = bank->tgi;
-	unsigned int gpio = d->hwirq;
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
 
-	gpiochip_unlock_as_irq(&tgi->gc, gpio);
+	gpiochip_unlock_as_irq(chip, d->hwirq);
 }
 
-static void tegra_gpio_irq_handler(struct irq_desc *desc)
+static void tegra_gpio_update_bank(struct gpio_bank *bank)
 {
-	unsigned int port, pin, gpio;
-	bool unmasked = false;
-	u32 lvl;
-	unsigned long sta;
-	struct irq_chip *chip = irq_desc_get_chip(desc);
-	struct tegra_gpio_bank *bank = irq_desc_get_handler_data(desc);
-	struct tegra_gpio_info *tgi = bank->tgi;
-
-	chained_irq_enter(chip, desc);
+	struct tegra_gpio_info *tgi = to_tegra_gpio_info(bank->chip);
+	struct tegra_gpio_bank *b = to_tegra_gpio_bank(bank);
+	unsigned int port;
 
 	for (port = 0; port < 4; port++) {
-		gpio = tegra_gpio_compose(bank->bank, port, 0);
-		sta = tegra_gpio_readl(tgi, GPIO_INT_STA(tgi, gpio)) &
-			tegra_gpio_readl(tgi, GPIO_INT_ENB(tgi, gpio));
-		lvl = tegra_gpio_readl(tgi, GPIO_INT_LVL(tgi, gpio));
-
-		for_each_set_bit(pin, &sta, 8) {
-			tegra_gpio_writel(tgi, 1 << pin,
-					  GPIO_INT_CLR(tgi, gpio));
-
-			/* if gpio is edge triggered, clear condition
-			 * before executing the handler so that we don't
-			 * miss edges
-			 */
-			if (!unmasked && lvl & (0x100 << pin)) {
-				unmasked = true;
-				chained_irq_exit(chip, desc);
-			}
+		unsigned int gpio = tegra_gpio_compose(b->index, port, 0);
+		u8 *pending = (u8 *)bank->pending;
+		u32 status, enable;
 
-			generic_handle_irq(irq_find_mapping(tgi->irq_domain,
-							    gpio + pin));
-		}
-	}
-
-	if (!unmasked)
-		chained_irq_exit(chip, desc);
+		status = tegra_gpio_readl(tgi, GPIO_INT_STA(tgi, gpio));
+		enable = tegra_gpio_readl(tgi, GPIO_INT_ENB(tgi, gpio));
 
+		pending[port] = status & enable;
+	}
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -410,7 +398,7 @@  static int tegra_gpio_resume(struct device *dev)
 
 	local_irq_save(flags);
 
-	for (b = 0; b < tgi->bank_count; b++) {
+	for (b = 0; b < tgi->gc.num_banks; b++) {
 		struct tegra_gpio_bank *bank = &tgi->bank_info[b];
 
 		for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@ -449,7 +437,7 @@  static int tegra_gpio_suspend(struct device *dev)
 	unsigned int b, p;
 
 	local_irq_save(flags);
-	for (b = 0; b < tgi->bank_count; b++) {
+	for (b = 0; b < tgi->gc.num_banks; b++) {
 		struct tegra_gpio_bank *bank = &tgi->bank_info[b];
 
 		for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@ -484,20 +472,26 @@  static int tegra_gpio_suspend(struct device *dev)
 
 static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
 {
-	struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	unsigned int gpio = d->hwirq;
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	unsigned int gpio = d->hwirq, parent_irq;
+	struct tegra_gpio_bank *b;
+	struct gpio_bank *bank;
 	u32 port, bit, mask;
 
+	bank = chip->banks[GPIO_BANK(gpio)];
+	b = to_tegra_gpio_bank(bank);
 	port = GPIO_PORT(gpio);
 	bit = GPIO_BIT(gpio);
 	mask = BIT(bit);
 
 	if (enable)
-		bank->wake_enb[port] |= mask;
+		b->wake_enb[port] |= mask;
 	else
-		bank->wake_enb[port] &= ~mask;
+		b->wake_enb[port] &= ~mask;
+
+	parent_irq = chip->irq.parents[bank->parent_irq];
 
-	return irq_set_irq_wake(bank->irq, enable);
+	return irq_set_irq_wake(parent_irq, enable);
 }
 #endif
 
@@ -511,7 +505,7 @@  static int dbg_gpio_show(struct seq_file *s, void *unused)
 	struct tegra_gpio_info *tgi = s->private;
 	unsigned int i, j;
 
-	for (i = 0; i < tgi->bank_count; i++) {
+	for (i = 0; i < tgi->gc.num_banks; i++) {
 		for (j = 0; j < 4; j++) {
 			unsigned int gpio = tegra_gpio_compose(i, j, 0);
 
@@ -561,17 +555,18 @@  static const struct dev_pm_ops tegra_gpio_pm_ops = {
 };
 
 /*
- * This lock class tells lockdep that GPIO irqs are in a different category
+ * This lock class tells lockdep that GPIO IRQs are in a different category
  * than their parents, so it won't report false recursion.
  */
-static struct lock_class_key gpio_lock_class;
+static struct lock_class_key tegra_gpio_lock_class;
 
 static int tegra_gpio_probe(struct platform_device *pdev)
 {
 	struct tegra_gpio_info *tgi;
 	struct resource *res;
 	struct tegra_gpio_bank *bank;
-	unsigned int gpio, i, j;
+	struct gpio_irq_chip *irq;
+	unsigned int i, j;
 	int ret;
 
 	tgi = devm_kzalloc(&pdev->dev, sizeof(*tgi), GFP_KERNEL);
@@ -580,14 +575,20 @@  static int tegra_gpio_probe(struct platform_device *pdev)
 
 	tgi->soc = of_device_get_match_data(&pdev->dev);
 	tgi->dev = &pdev->dev;
+	irq = &tgi->gc.irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	tgi->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tgi->regs))
+		return PTR_ERR(tgi->regs);
 
 	ret = platform_irq_count(pdev);
 	if (ret < 0)
 		return ret;
 
-	tgi->bank_count = ret;
+	tgi->gc.num_banks = ret;
 
-	if (!tgi->bank_count) {
+	if (!tgi->gc.num_banks) {
 		dev_err(&pdev->dev, "Missing IRQ resource\n");
 		return -ENODEV;
 	}
@@ -602,7 +603,7 @@  static int tegra_gpio_probe(struct platform_device *pdev)
 	tgi->gc.get_direction		= tegra_gpio_get_direction;
 	tgi->gc.to_irq			= tegra_gpio_to_irq;
 	tgi->gc.base			= 0;
-	tgi->gc.ngpio			= tgi->bank_count * 32;
+	tgi->gc.ngpio			= tgi->gc.num_banks * 32;
 	tgi->gc.parent			= &pdev->dev;
 	tgi->gc.of_node			= pdev->dev.of_node;
 
@@ -616,76 +617,66 @@  static int tegra_gpio_probe(struct platform_device *pdev)
 	tgi->ic.irq_set_wake		= tegra_gpio_irq_set_wake;
 #endif
 
+	irq = &tgi->gc.irq;
+	irq->chip = &tgi->ic;
+	irq->handler = handle_simple_irq;
+	irq->lock_key = &tegra_gpio_lock_class;
+	irq->default_type = IRQ_TYPE_NONE;
+	irq->parent_handler = gpio_irq_chip_banked_chained_handler;
+	irq->update_bank = tegra_gpio_update_bank;
+
+	irq->parents = devm_kcalloc(&pdev->dev, tgi->gc.num_banks,
+				    sizeof(unsigned int), GFP_KERNEL);
+	if (!irq->parents)
+		return -ENOMEM;
+
+	irq->num_parents = tgi->gc.num_banks;
+
 	platform_set_drvdata(pdev, tgi);
 
 	if (tgi->soc->debounce_supported)
 		tgi->gc.set_config = tegra_gpio_set_config;
 
-	tgi->bank_info = devm_kcalloc(&pdev->dev, tgi->bank_count,
+	tgi->bank_info = devm_kcalloc(&pdev->dev, tgi->gc.num_banks,
 				      sizeof(*tgi->bank_info), GFP_KERNEL);
 	if (!tgi->bank_info)
 		return -ENOMEM;
 
-	tgi->irq_domain = irq_domain_add_linear(pdev->dev.of_node,
-						tgi->gc.ngpio,
-						&irq_domain_simple_ops, NULL);
-	if (!tgi->irq_domain)
-		return -ENODEV;
+	tgi->gc.banks = devm_kcalloc(&pdev->dev, tgi->gc.num_banks,
+				     sizeof(struct gpio_bank *),
+				     GFP_KERNEL);
+	if (!tgi->gc.banks)
+		return -ENOMEM;
 
-	for (i = 0; i < tgi->bank_count; i++) {
+	for (i = 0; i < tgi->gc.num_banks; i++) {
 		ret = platform_get_irq(pdev, i);
 		if (ret < 0) {
 			dev_err(&pdev->dev, "Missing IRQ resource: %d\n", ret);
 			return ret;
 		}
 
+		irq->parents[i] = ret;
+
 		bank = &tgi->bank_info[i];
-		bank->bank = i;
-		bank->irq = ret;
-		bank->tgi = tgi;
-	}
+		bank->bank.chip = &tgi->gc;
+		bank->bank.parent_irq = i;
+		bank->bank.num_lines = 32;
+		bank->index = i;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	tgi->regs = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(tgi->regs))
-		return PTR_ERR(tgi->regs);
+		tgi->gc.banks[i] = &bank->bank;
 
-	for (i = 0; i < tgi->bank_count; i++) {
 		for (j = 0; j < 4; j++) {
-			int gpio = tegra_gpio_compose(i, j, 0);
+			unsigned int gpio = tegra_gpio_compose(i, j, 0);
 
 			tegra_gpio_writel(tgi, 0x00, GPIO_INT_ENB(tgi, gpio));
+			spin_lock_init(&bank->lvl_lock[j]);
+			spin_lock_init(&bank->dbc_lock[j]);
 		}
 	}
 
 	ret = devm_gpiochip_add_data(&pdev->dev, &tgi->gc, tgi);
-	if (ret < 0) {
-		irq_domain_remove(tgi->irq_domain);
+	if (ret < 0)
 		return ret;
-	}
-
-	for (gpio = 0; gpio < tgi->gc.ngpio; gpio++) {
-		int irq = irq_create_mapping(tgi->irq_domain, gpio);
-		/* No validity check; all Tegra GPIOs are valid IRQs */
-
-		bank = &tgi->bank_info[GPIO_BANK(gpio)];
-
-		irq_set_lockdep_class(irq, &gpio_lock_class);
-		irq_set_chip_data(irq, bank);
-		irq_set_chip_and_handler(irq, &tgi->ic, handle_simple_irq);
-	}
-
-	for (i = 0; i < tgi->bank_count; i++) {
-		bank = &tgi->bank_info[i];
-
-		irq_set_chained_handler_and_data(bank->irq,
-						 tegra_gpio_irq_handler, bank);
-
-		for (j = 0; j < 4; j++) {
-			spin_lock_init(&bank->lvl_lock[j]);
-			spin_lock_init(&bank->dbc_lock[j]);
-		}
-	}
 
 	tegra_gpio_debuginit(tgi);