Merge remote branch 'gcl/next' into next
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* GPIOs on MPC8349/8572/8610 and compatible
|
||||
* GPIOs on MPC512x/8349/8572/8610 and compatible
|
||||
*
|
||||
* Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
|
||||
*
|
||||
@@ -26,6 +26,7 @@
|
||||
#define GPIO_IER 0x0c
|
||||
#define GPIO_IMR 0x10
|
||||
#define GPIO_ICR 0x14
|
||||
#define GPIO_ICR2 0x18
|
||||
|
||||
struct mpc8xxx_gpio_chip {
|
||||
struct of_mm_gpio_chip mm_gc;
|
||||
@@ -37,6 +38,7 @@ struct mpc8xxx_gpio_chip {
|
||||
*/
|
||||
u32 data;
|
||||
struct irq_host *irq;
|
||||
void *of_dev_id_data;
|
||||
};
|
||||
|
||||
static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
|
||||
@@ -215,6 +217,51 @@ static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpc512x_irq_set_type(unsigned int virq, unsigned int flow_type)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
|
||||
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
|
||||
unsigned long gpio = virq_to_hw(virq);
|
||||
void __iomem *reg;
|
||||
unsigned int shift;
|
||||
unsigned long flags;
|
||||
|
||||
if (gpio < 16) {
|
||||
reg = mm->regs + GPIO_ICR;
|
||||
shift = (15 - gpio) * 2;
|
||||
} else {
|
||||
reg = mm->regs + GPIO_ICR2;
|
||||
shift = (15 - (gpio % 16)) * 2;
|
||||
}
|
||||
|
||||
switch (flow_type) {
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
clrsetbits_be32(reg, 3 << shift, 2 << shift);
|
||||
spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
clrsetbits_be32(reg, 3 << shift, 1 << shift);
|
||||
spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
clrbits32(reg, 3 << shift);
|
||||
spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip mpc8xxx_irq_chip = {
|
||||
.name = "mpc8xxx-gpio",
|
||||
.unmask = mpc8xxx_irq_unmask,
|
||||
@@ -226,6 +273,11 @@ static struct irq_chip mpc8xxx_irq_chip = {
|
||||
static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
|
||||
irq_hw_number_t hw)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
|
||||
|
||||
if (mpc8xxx_gc->of_dev_id_data)
|
||||
mpc8xxx_irq_chip.set_type = mpc8xxx_gc->of_dev_id_data;
|
||||
|
||||
set_irq_chip_data(virq, h->host_data);
|
||||
set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
|
||||
set_irq_type(virq, IRQ_TYPE_NONE);
|
||||
@@ -253,11 +305,20 @@ static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
|
||||
.xlate = mpc8xxx_gpio_irq_xlate,
|
||||
};
|
||||
|
||||
static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
|
||||
{ .compatible = "fsl,mpc8349-gpio", },
|
||||
{ .compatible = "fsl,mpc8572-gpio", },
|
||||
{ .compatible = "fsl,mpc8610-gpio", },
|
||||
{ .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
|
||||
{}
|
||||
};
|
||||
|
||||
static void __init mpc8xxx_add_controller(struct device_node *np)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc;
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
struct gpio_chip *gc;
|
||||
const struct of_device_id *id;
|
||||
unsigned hwirq;
|
||||
int ret;
|
||||
|
||||
@@ -297,6 +358,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
|
||||
if (!mpc8xxx_gc->irq)
|
||||
goto skip_irq;
|
||||
|
||||
id = of_match_node(mpc8xxx_gpio_ids, np);
|
||||
if (id)
|
||||
mpc8xxx_gc->of_dev_id_data = id->data;
|
||||
|
||||
mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
|
||||
|
||||
/* ack and mask all irqs */
|
||||
@@ -321,13 +386,7 @@ static int __init mpc8xxx_add_gpiochips(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
for_each_compatible_node(np, NULL, "fsl,mpc8349-gpio")
|
||||
mpc8xxx_add_controller(np);
|
||||
|
||||
for_each_compatible_node(np, NULL, "fsl,mpc8572-gpio")
|
||||
mpc8xxx_add_controller(np);
|
||||
|
||||
for_each_compatible_node(np, NULL, "fsl,mpc8610-gpio")
|
||||
for_each_matching_node(np, mpc8xxx_gpio_ids)
|
||||
mpc8xxx_add_controller(np);
|
||||
|
||||
for_each_compatible_node(np, NULL, "fsl,qoriq-gpio")
|
||||
|
Reference in New Issue
Block a user