Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 296893
b: refs/heads/master
c: 78518ff
h: refs/heads/master
i:
  296891: e5891f3
v: v3
  • Loading branch information
Benoit Cousson authored and Samuel Ortiz committed Mar 22, 2012
1 parent e4ee311 commit fb99ddb
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 38 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1b8f333ff49f778a1215f65754c31c02408d1d08
refs/heads/master: 78518ffa08fceee42d61359303c58bdd0a82033f
29 changes: 5 additions & 24 deletions trunk/drivers/mfd/twl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,6 @@

#define TWL_MODULE_LAST TWL4030_MODULE_LAST

#define TWL4030_NR_IRQS 8
#define TWL6030_NR_IRQS 20

/* Base Address defns for twl4030_map[] */

/* subchip/slave 0 - USB ID */
Expand Down Expand Up @@ -1186,17 +1183,12 @@ static int __devinit
twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int irq_base;
int irq_end;
int status;
unsigned i;
struct twl4030_platform_data *pdata = client->dev.platform_data;
struct device_node *node = client->dev.of_node;
u8 temp;
int ret = 0;
int nr_irqs = TWL4030_NR_IRQS;

if ((id->driver_data) & TWL6030_CLASS)
nr_irqs = TWL6030_NR_IRQS;

if (node && !pdata) {
/*
Expand All @@ -1215,17 +1207,6 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
return -EINVAL;
}

status = irq_alloc_descs(-1, 0, nr_irqs, 0);
if (IS_ERR_VALUE(status)) {
dev_err(&client->dev, "Fail to allocate IRQ descs\n");
return status;
}

irq_base = status;
irq_end = irq_base + nr_irqs;
irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
&irq_domain_simple_ops, NULL);

if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
dev_dbg(&client->dev, "can't talk I2C?\n");
return -EIO;
Expand Down Expand Up @@ -1280,15 +1261,15 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (client->irq) {
if (twl_class_is_4030()) {
twl4030_init_chip_irq(id->name);
status = twl4030_init_irq(client->irq, irq_base,
irq_end);
irq_base = twl4030_init_irq(&client->dev, client->irq);
} else {
status = twl6030_init_irq(client->irq, irq_base,
irq_end);
irq_base = twl6030_init_irq(&client->dev, client->irq);
}

if (status < 0)
if (irq_base < 0) {
status = irq_base;
goto fail;
}
}

/* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/mfd/twl-core.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#ifndef __TWL_CORE_H__
#define __TWL_CORE_H__

extern int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
extern int twl6030_init_irq(struct device *dev, int irq_num);
extern int twl6030_exit_irq(void);
extern int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
extern int twl4030_init_irq(struct device *dev, int irq_num);
extern int twl4030_exit_irq(void);
extern int twl4030_init_chip_irq(const char *chip);

Expand Down
29 changes: 27 additions & 2 deletions trunk/drivers/mfd/twl4030-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@
*/

#include <linux/init.h>
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>

#include <linux/of.h>
#include <linux/irqdomain.h>
#include <linux/i2c/twl.h>

#include "twl-core.h"
Expand All @@ -53,6 +56,8 @@
* base + 8 .. base + 15 SIH for PWR_INT
* base + 16 .. base + 33 SIH for GPIO
*/
#define TWL4030_CORE_NR_IRQS 8
#define TWL4030_PWR_NR_IRQS 8

/* PIH register offsets */
#define REG_PIH_ISR_P1 0x01
Expand Down Expand Up @@ -695,13 +700,33 @@ int twl4030_sih_setup(int module)
/* FIXME pass in which interrupt line we'll use ... */
#define twl_irq_line 0

int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
int twl4030_init_irq(struct device *dev, int irq_num)
{
static struct irq_chip twl4030_irq_chip;
int irq_base, irq_end, nr_irqs;
struct device_node *node = dev->of_node;

int status;
int i;

/*
* TWL core and pwr interrupts must be contiguous because
* the hwirqs numbers are defined contiguously from 1 to 15.
* Create only one domain for both.
*/
nr_irqs = TWL4030_PWR_NR_IRQS + TWL4030_CORE_NR_IRQS;

irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
if (IS_ERR_VALUE(irq_base)) {
dev_err(dev, "Fail to allocate IRQ descs\n");
return irq_base;
}

irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
&irq_domain_simple_ops, NULL);

irq_end = irq_base + TWL4030_CORE_NR_IRQS;

/*
* Mask and clear all TWL4030 interrupts since initially we do
* not have any TWL4030 module interrupt handlers present
Expand Down Expand Up @@ -747,7 +772,7 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
goto fail_rqirq;
}

return status;
return irq_base;
fail_rqirq:
/* clean up twl4030_sih_setup */
fail:
Expand Down
31 changes: 22 additions & 9 deletions trunk/drivers/mfd/twl6030-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#include <linux/i2c/twl.h>
#include <linux/platform_device.h>
#include <linux/suspend.h>
#include <linux/of.h>
#include <linux/irqdomain.h>

#include "twl-core.h"

Expand All @@ -53,6 +55,7 @@
* specifies mapping between interrupt number and the associated module.
*
*/
#define TWL6030_NR_IRQS 20

static int twl6030_interrupt_mapping[24] = {
PWR_INTR_OFFSET, /* Bit 0 PWRON */
Expand Down Expand Up @@ -246,11 +249,6 @@ static int twl6030_irq_set_wake(struct irq_data *d, unsigned int on)
return 0;
}

/*----------------------------------------------------------------------*/

static unsigned twl6030_irq_next;

/*----------------------------------------------------------------------*/
int twl6030_interrupt_unmask(u8 bit_mask, u8 offset)
{
int ret;
Expand Down Expand Up @@ -350,8 +348,10 @@ int twl6030_mmc_card_detect(struct device *dev, int slot)
}
EXPORT_SYMBOL(twl6030_mmc_card_detect);

int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
int twl6030_init_irq(struct device *dev, int irq_num)
{
struct device_node *node = dev->of_node;
int nr_irqs, irq_base, irq_end;

int status = 0;
int i;
Expand All @@ -360,6 +360,20 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
u8 mask[4];

static struct irq_chip twl6030_irq_chip;

nr_irqs = TWL6030_NR_IRQS;

irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
if (IS_ERR_VALUE(irq_base)) {
dev_err(dev, "Fail to allocate IRQ descs\n");
return irq_base;
}

irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
&irq_domain_simple_ops, NULL);

irq_end = irq_base + nr_irqs;

mask[1] = 0xFF;
mask[2] = 0xFF;
mask[3] = 0xFF;
Expand Down Expand Up @@ -387,9 +401,8 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
activate_irq(i);
}

twl6030_irq_next = i;
pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
irq_num, irq_base, twl6030_irq_next - 1);
irq_num, irq_base, irq_end);

/* install an irq handler to demultiplex the TWL6030 interrupt */
init_completion(&irq_event);
Expand All @@ -410,7 +423,7 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)

twl_irq = irq_num;
register_pm_notifier(&twl6030_irq_pm_notifier_block);
return status;
return irq_base;

fail_kthread:
free_irq(irq_num, &irq_event);
Expand Down

0 comments on commit fb99ddb

Please sign in to comment.