Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 3175
b: refs/heads/master
c: c498288
h: refs/heads/master
i:
  3173: 26a44c9
  3171: 20298f3
  3167: 8075c60
v: v3
  • Loading branch information
Lennert Buytenhek authored and Russell King committed Jun 24, 2005
1 parent 5dc4091 commit 790281d
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 60 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: c6b56949de86694d837750a0a89c766b9871e81c
refs/heads/master: c4982887cacf2122bc256e901598b58caf4a34be
85 changes: 67 additions & 18 deletions trunk/arch/arm/mach-ixp2000/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include <asm/mach/time.h>
#include <asm/mach/irq.h>

#include <asm/arch/gpio.h>

static DEFINE_SPINLOCK(ixp2000_slowport_lock);
static unsigned long ixp2000_slowport_irq_flags;

Expand Down Expand Up @@ -179,7 +181,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)

/* clear timer 1 */
ixp2000_reg_write(IXP2000_T1_CLR, 1);

while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
timer_tick(regs);
next_jiffy_time -= ticks_per_jiffy;
Expand Down Expand Up @@ -238,35 +240,40 @@ void __init ixp2000_init_time(unsigned long tick_rate)
/*************************************************************************
* GPIO helpers
*************************************************************************/
static unsigned long GPIO_IRQ_rising_edge;
static unsigned long GPIO_IRQ_falling_edge;
static unsigned long GPIO_IRQ_rising_edge;
static unsigned long GPIO_IRQ_level_low;
static unsigned long GPIO_IRQ_level_high;

void gpio_line_config(int line, int style)
static void update_gpio_int_csrs(void)
{
ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
}

void gpio_line_config(int line, int direction)
{
unsigned long flags;

local_irq_save(flags);
if (direction == GPIO_OUT) {
irq_desc[line + IRQ_IXP2000_GPIO0].valid = 0;

if(style == GPIO_OUT) {
/* if it's an output, it ain't an interrupt anymore */
ixp2000_reg_write(IXP2000_GPIO_PDSR, (1 << line));
GPIO_IRQ_falling_edge &= ~(1 << line);
GPIO_IRQ_rising_edge &= ~(1 << line);
GPIO_IRQ_level_low &= ~(1 << line);
GPIO_IRQ_level_high &= ~(1 << line);
ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
irq_desc[line+IRQ_IXP2000_GPIO0].valid = 0;
} else if(style == GPIO_IN) {
ixp2000_reg_write(IXP2000_GPIO_PDCR, (1 << line));
update_gpio_int_csrs();

ixp2000_reg_write(IXP2000_GPIO_PDSR, 1 << line);
} else if (direction == GPIO_IN) {
ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
}

local_irq_restore(flags);
}
}


/*************************************************************************
Expand All @@ -285,9 +292,50 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str
}
}

static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type)
{
int line = irq - IRQ_IXP2000_GPIO0;

/*
* First, configure this GPIO line as an input.
*/
ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);

/*
* Then, set the proper trigger type.
*/
if (type & IRQT_FALLING)
GPIO_IRQ_falling_edge |= 1 << line;
else
GPIO_IRQ_falling_edge &= ~(1 << line);
if (type & IRQT_RISING)
GPIO_IRQ_rising_edge |= 1 << line;
else
GPIO_IRQ_rising_edge &= ~(1 << line);
if (type & IRQT_LOW)
GPIO_IRQ_level_low |= 1 << line;
else
GPIO_IRQ_level_low &= ~(1 << line);
if (type & IRQT_HIGH)
GPIO_IRQ_level_high |= 1 << line;
else
GPIO_IRQ_level_high &= ~(1 << line);
update_gpio_int_csrs();

/*
* Finally, mark the corresponding IRQ as valid.
*/
irq_desc[irq].valid = 1;

return 0;
}

static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
{
ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));

ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
}

Expand All @@ -302,6 +350,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq)
}

static struct irqchip ixp2000_GPIO_irq_chip = {
.type = ixp2000_GPIO_irq_type,
.ack = ixp2000_GPIO_irq_mask_ack,
.mask = ixp2000_GPIO_irq_mask,
.unmask = ixp2000_GPIO_irq_unmask
Expand Down Expand Up @@ -338,7 +387,7 @@ static void ixp2000_irq_mask(unsigned int irq)

static void ixp2000_irq_unmask(unsigned int irq)
{
ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq));
ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq));
}

static struct irqchip ixp2000_irq_chip = {
Expand Down Expand Up @@ -375,16 +424,16 @@ void __init ixp2000_init_irq(void)
* our mask/unmask code much simpler.
*/
for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) {
if((1 << irq) & IXP2000_VALID_IRQ_MASK) {
if ((1 << irq) & IXP2000_VALID_IRQ_MASK) {
set_irq_chip(irq, &ixp2000_irq_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID);
} else set_irq_flags(irq, 0);
}

/*
* GPIO IRQs are invalid until someone sets the interrupt mode
* by calling gpio_line_set();
* by calling set_irq_type().
*/
for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) {
set_irq_chip(irq, &ixp2000_GPIO_irq_chip);
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/i2c/busses/i2c-ixp2000.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>

#include <asm/hardware.h> /* Pick up IXP42000-specific bits */
#include <asm/hardware.h> /* Pick up IXP2000-specific bits */
#include <asm/arch/gpio.h>

static inline int ixp2000_scl_pin(void *data)
{
Expand Down
31 changes: 12 additions & 19 deletions trunk/include/asm-arm/arch-ixp2000/gpio.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* include/asm-arm/arch-ixp2000/ixp2000-gpio.h
* include/asm-arm/arch-ixp2000/gpio.h
*
* Copyright (C) 2002 Intel Corporation.
*
Expand All @@ -16,26 +16,18 @@
* Use this instead of directly setting the GPIO registers.
* GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb)
*/
#ifndef _ASM_ARCH_IXP2000_GPIO_H_
#define _ASM_ARCH_IXP2000_GPIO_H_
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H

#ifndef __ASSEMBLY__
#define GPIO_OUT 0x0
#define GPIO_IN 0x80

#define GPIO_IN 0
#define GPIO_OUT 1

#define IXP2000_GPIO_LOW 0
#define IXP2000_GPIO_HIGH 1

#define GPIO_NO_EDGES 0
#define GPIO_FALLING_EDGE 1
#define GPIO_RISING_EDGE 2
#define GPIO_BOTH_EDGES 3
#define GPIO_LEVEL_LOW 4
#define GPIO_LEVEL_HIGH 8

extern void set_GPIO_IRQ_edge(int gpio_nr, int edge);
extern void set_GPIO_IRQ_level(int gpio_nr, int level);
extern void gpio_line_config(int line, int style);
extern void gpio_line_config(int line, int direction);

static inline int gpio_line_get(int line)
{
Expand All @@ -45,11 +37,12 @@ static inline int gpio_line_get(int line)
static inline void gpio_line_set(int line, int value)
{
if (value == IXP2000_GPIO_HIGH) {
ixp_reg_write(IXP2000_GPIO_POSR, BIT(line));
} else if (value == IXP2000_GPIO_LOW)
ixp_reg_write(IXP2000_GPIO_POCR, BIT(line));
ixp2000_reg_write(IXP2000_GPIO_POSR, 1 << line);
} else if (value == IXP2000_GPIO_LOW) {
ixp2000_reg_write(IXP2000_GPIO_POCR, 1 << line);
}
}

#endif /* !__ASSEMBLY__ */
#endif /* ASM_ARCH_IXP2000_GPIO_H_ */

#endif /* ASM_ARCH_IXP2000_GPIO_H_ */
22 changes: 1 addition & 21 deletions trunk/include/asm-arm/arch-ixp2000/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,30 +138,10 @@ struct ixp2000_flash_data {
unsigned long (*bank_setup)(unsigned long);
};

/*
* GPIO helper functions
*/
#define GPIO_IN 0
#define GPIO_OUT 1

extern void gpio_line_config(int line, int style);

static inline int gpio_line_get(int line)
{
return (((*IXP2000_GPIO_PLR) >> line) & 1);
}

static inline void gpio_line_set(int line, int value)
{
if (value)
ixp2000_reg_write(IXP2000_GPIO_POSR, (1 << line));
else
ixp2000_reg_write(IXP2000_GPIO_POCR, (1 << line));
}

struct ixp2000_i2c_pins {
unsigned long sda_pin;
unsigned long scl_pin;
};


#endif /* !__ASSEMBLY__ */

0 comments on commit 790281d

Please sign in to comment.