Davinci: gpio - register layout invariant inlines
This patch renders the inlined gpio accessors in gpio.h independent of the underlying controller's register layout. This is done by including three new fields in davinci_gpio_controller to hold the addresses of the set, clear, and in data registers. Other changes: 1. davinci_gpio_regs structure definition moved to gpio.c. This structure is no longer common across all davinci socs (davinci_gpio_controller is). 2. controller base address calculation code (gpio2controller()) moved to gpio.c as this was no longer necessary for the inline implementation. 3. modified inline range checks to use davinci_soc_info.gpio_num instead of DAVINCI_N_GPIO. Signed-off-by: Cyril Chemparathy <cyril@ti.com> Tested-by: Sandeep Paulraj <s-paulraj@ti.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
This commit is contained in:
committed by
Kevin Hilman
parent
99e9e52de6
commit
c12f415a91
@@ -20,6 +20,19 @@
|
|||||||
|
|
||||||
#include <asm/mach/irq.h>
|
#include <asm/mach/irq.h>
|
||||||
|
|
||||||
|
struct davinci_gpio_regs {
|
||||||
|
u32 dir;
|
||||||
|
u32 out_data;
|
||||||
|
u32 set_data;
|
||||||
|
u32 clr_data;
|
||||||
|
u32 in_data;
|
||||||
|
u32 set_rising;
|
||||||
|
u32 clr_rising;
|
||||||
|
u32 set_falling;
|
||||||
|
u32 clr_falling;
|
||||||
|
u32 intstat;
|
||||||
|
};
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(gpio_lock);
|
static DEFINE_SPINLOCK(gpio_lock);
|
||||||
|
|
||||||
#define chip2controller(chip) \
|
#define chip2controller(chip) \
|
||||||
@@ -27,10 +40,24 @@ static DEFINE_SPINLOCK(gpio_lock);
|
|||||||
|
|
||||||
static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
|
static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
|
||||||
|
|
||||||
/* create a non-inlined version */
|
|
||||||
static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
|
static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
|
||||||
{
|
{
|
||||||
return __gpio_to_controller(gpio);
|
void __iomem *ptr;
|
||||||
|
void __iomem *base = davinci_soc_info.gpio_base;
|
||||||
|
|
||||||
|
if (gpio < 32 * 1)
|
||||||
|
ptr = base + 0x10;
|
||||||
|
else if (gpio < 32 * 2)
|
||||||
|
ptr = base + 0x38;
|
||||||
|
else if (gpio < 32 * 3)
|
||||||
|
ptr = base + 0x60;
|
||||||
|
else if (gpio < 32 * 4)
|
||||||
|
ptr = base + 0x88;
|
||||||
|
else if (gpio < 32 * 5)
|
||||||
|
ptr = base + 0xb0;
|
||||||
|
else
|
||||||
|
ptr = NULL;
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct davinci_gpio_regs __iomem *irq2regs(int irq)
|
static inline struct davinci_gpio_regs __iomem *irq2regs(int irq)
|
||||||
@@ -116,6 +143,7 @@ static int __init davinci_gpio_setup(void)
|
|||||||
int i, base;
|
int i, base;
|
||||||
unsigned ngpio;
|
unsigned ngpio;
|
||||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
||||||
|
struct davinci_gpio_regs *regs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The gpio banks conceptually expose a segmented bitmap,
|
* The gpio banks conceptually expose a segmented bitmap,
|
||||||
@@ -144,11 +172,18 @@ static int __init davinci_gpio_setup(void)
|
|||||||
if (chips[i].chip.ngpio > 32)
|
if (chips[i].chip.ngpio > 32)
|
||||||
chips[i].chip.ngpio = 32;
|
chips[i].chip.ngpio = 32;
|
||||||
|
|
||||||
chips[i].regs = gpio2regs(base);
|
regs = gpio2regs(base);
|
||||||
|
chips[i].regs = regs;
|
||||||
|
chips[i].set_data = ®s->set_data;
|
||||||
|
chips[i].clr_data = ®s->clr_data;
|
||||||
|
chips[i].in_data = ®s->in_data;
|
||||||
|
|
||||||
gpiochip_add(&chips[i].chip);
|
gpiochip_add(&chips[i].chip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
soc_info->gpio_ctlrs = chips;
|
||||||
|
soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
|
||||||
|
|
||||||
davinci_gpio_irq_setup();
|
davinci_gpio_irq_setup();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -37,6 +37,8 @@ struct davinci_timer_info {
|
|||||||
unsigned int clocksource_id;
|
unsigned int clocksource_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct davinci_gpio_controller;
|
||||||
|
|
||||||
/* SoC specific init support */
|
/* SoC specific init support */
|
||||||
struct davinci_soc_info {
|
struct davinci_soc_info {
|
||||||
struct map_desc *io_desc;
|
struct map_desc *io_desc;
|
||||||
@@ -61,6 +63,8 @@ struct davinci_soc_info {
|
|||||||
unsigned gpio_num;
|
unsigned gpio_num;
|
||||||
unsigned gpio_irq;
|
unsigned gpio_irq;
|
||||||
unsigned gpio_unbanked;
|
unsigned gpio_unbanked;
|
||||||
|
struct davinci_gpio_controller *gpio_ctlrs;
|
||||||
|
int gpio_ctlrs_num;
|
||||||
struct platform_device *serial_dev;
|
struct platform_device *serial_dev;
|
||||||
struct emac_platform_data *emac_pdata;
|
struct emac_platform_data *emac_pdata;
|
||||||
dma_addr_t sram_dma;
|
dma_addr_t sram_dma;
|
||||||
|
@@ -45,23 +45,13 @@
|
|||||||
/* Convert GPIO signal to GPIO pin number */
|
/* Convert GPIO signal to GPIO pin number */
|
||||||
#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio))
|
#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio))
|
||||||
|
|
||||||
struct davinci_gpio_regs {
|
|
||||||
u32 dir;
|
|
||||||
u32 out_data;
|
|
||||||
u32 set_data;
|
|
||||||
u32 clr_data;
|
|
||||||
u32 in_data;
|
|
||||||
u32 set_rising;
|
|
||||||
u32 clr_rising;
|
|
||||||
u32 set_falling;
|
|
||||||
u32 clr_falling;
|
|
||||||
u32 intstat;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct davinci_gpio_controller {
|
struct davinci_gpio_controller {
|
||||||
struct davinci_gpio_regs __iomem *regs;
|
|
||||||
struct gpio_chip chip;
|
struct gpio_chip chip;
|
||||||
int irq_base;
|
int irq_base;
|
||||||
|
void __iomem *regs;
|
||||||
|
void __iomem *set_data;
|
||||||
|
void __iomem *clr_data;
|
||||||
|
void __iomem *in_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
|
/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
|
||||||
@@ -73,25 +63,16 @@ struct davinci_gpio_controller {
|
|||||||
*
|
*
|
||||||
* These are NOT part of the cross-platform GPIO interface
|
* These are NOT part of the cross-platform GPIO interface
|
||||||
*/
|
*/
|
||||||
static inline struct davinci_gpio_regs __iomem *
|
static inline struct davinci_gpio_controller *
|
||||||
__gpio_to_controller(unsigned gpio)
|
__gpio_to_controller(unsigned gpio)
|
||||||
{
|
{
|
||||||
void __iomem *ptr;
|
struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs;
|
||||||
void __iomem *base = davinci_soc_info.gpio_base;
|
int index = gpio / 32;
|
||||||
|
|
||||||
if (gpio < 32 * 1)
|
if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num)
|
||||||
ptr = base + 0x10;
|
return NULL;
|
||||||
else if (gpio < 32 * 2)
|
|
||||||
ptr = base + 0x38;
|
return ctlrs + index;
|
||||||
else if (gpio < 32 * 3)
|
|
||||||
ptr = base + 0x60;
|
|
||||||
else if (gpio < 32 * 4)
|
|
||||||
ptr = base + 0x88;
|
|
||||||
else if (gpio < 32 * 5)
|
|
||||||
ptr = base + 0xb0;
|
|
||||||
else
|
|
||||||
ptr = NULL;
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 __gpio_mask(unsigned gpio)
|
static inline u32 __gpio_mask(unsigned gpio)
|
||||||
@@ -107,16 +88,16 @@ static inline u32 __gpio_mask(unsigned gpio)
|
|||||||
*/
|
*/
|
||||||
static inline void gpio_set_value(unsigned gpio, int value)
|
static inline void gpio_set_value(unsigned gpio, int value)
|
||||||
{
|
{
|
||||||
if (__builtin_constant_p(value) && gpio < DAVINCI_N_GPIO) {
|
if (__builtin_constant_p(value) && gpio < davinci_soc_info.gpio_num) {
|
||||||
struct davinci_gpio_regs __iomem *g;
|
struct davinci_gpio_controller *ctlr;
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
g = __gpio_to_controller(gpio);
|
ctlr = __gpio_to_controller(gpio);
|
||||||
mask = __gpio_mask(gpio);
|
mask = __gpio_mask(gpio);
|
||||||
if (value)
|
if (value)
|
||||||
__raw_writel(mask, &g->set_data);
|
__raw_writel(mask, ctlr->set_data);
|
||||||
else
|
else
|
||||||
__raw_writel(mask, &g->clr_data);
|
__raw_writel(mask, ctlr->clr_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,18 +115,18 @@ static inline void gpio_set_value(unsigned gpio, int value)
|
|||||||
*/
|
*/
|
||||||
static inline int gpio_get_value(unsigned gpio)
|
static inline int gpio_get_value(unsigned gpio)
|
||||||
{
|
{
|
||||||
struct davinci_gpio_regs __iomem *g;
|
struct davinci_gpio_controller *ctlr;
|
||||||
|
|
||||||
if (!__builtin_constant_p(gpio) || gpio >= DAVINCI_N_GPIO)
|
if (!__builtin_constant_p(gpio) || gpio >= davinci_soc_info.gpio_num)
|
||||||
return __gpio_get_value(gpio);
|
return __gpio_get_value(gpio);
|
||||||
|
|
||||||
g = __gpio_to_controller(gpio);
|
ctlr = __gpio_to_controller(gpio);
|
||||||
return __gpio_mask(gpio) & __raw_readl(&g->in_data);
|
return __gpio_mask(gpio) & __raw_readl(ctlr->in_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int gpio_cansleep(unsigned gpio)
|
static inline int gpio_cansleep(unsigned gpio)
|
||||||
{
|
{
|
||||||
if (__builtin_constant_p(gpio) && gpio < DAVINCI_N_GPIO)
|
if (__builtin_constant_p(gpio) && gpio < davinci_soc_info.gpio_num)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return __gpio_cansleep(gpio);
|
return __gpio_cansleep(gpio);
|
||||||
|
Reference in New Issue
Block a user