Commit b7f720d6 authored by Manuel Lauss's avatar Manuel Lauss Committed by Ralf Baechle

MIPS: Alchemy: Clean up GPIO registers and accessors

remove au_readl/au_writel, remove the predefined GPIO1/2 KSEG1 register
addresses and fix the fallout in all boards and drivers.

This also fixes a bug in the mtx-1_wdt driver which was introduced by
commit 6ea8115b
("Convert mtx1 wdt to be a platform device and use generic GPIO API")
before this patch mtx-1_wdt only modified GPIO215, the patch then
used the gpio resource information as bit index into the GPIO2 register
but the conversion to the GPIO API didn't realize that.
With this patch the drivers original behaviour is restored and GPIO15
is left alone.
Signed-off-by: default avatarManuel Lauss <manuel.lauss@googlemail.com>
Cc: Florian Fainelli <florian@openwrt.org>
To: Linux-MIPS <linux-mips@linux-mips.org>
Cc: linux-watchdog@vger.kernel.org
Cc: Wim Van Sebroeck <wim@iguana.be>
Patchwork: https://patchwork.linux-mips.org/patch/2381/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org
parent 5d4ddcb4
......@@ -65,7 +65,7 @@ void __init board_setup(void)
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);
au_writel(0, SYS_PINSTATERD);
alchemy_gpio1_input_enable();
udelay(100);
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
......
......@@ -56,7 +56,7 @@ void __init board_setup(void)
sys_clksrc = sys_freqctrl = pin_func = 0;
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);
au_writel(0, SYS_PINSTATERD);
alchemy_gpio1_input_enable();
udelay(100);
/* GPIO201 is input for PCMCIA card detect */
......
......@@ -87,7 +87,7 @@ void __init board_setup(void)
au_writel(SYS_PF_NI2, SYS_PINFUNC);
/* Initialize GPIO */
au_writel(0xFFFFFFFF, SYS_TRIOUTCLR);
au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR);
alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */
alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */
alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */
......
......@@ -53,8 +53,8 @@ static struct platform_device mtx1_button = {
static struct resource mtx1_wdt_res[] = {
[0] = {
.start = 15,
.end = 15,
.start = 215,
.end = 215,
.name = "mtx1-wdt-gpio",
.flags = IORESOURCE_IRQ,
}
......
......@@ -702,7 +702,9 @@ enum soc_au1200_ints {
#define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */
#define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */
#define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */
#define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */
#define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */
#define AU1000_SYS_PHYS_ADDR 0x11900000 /* 01234 */
#define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */
#define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */
#define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */
......@@ -717,7 +719,6 @@ enum soc_au1200_ints {
#define IRDA_PHYS_ADDR 0x10300000
#define SSI0_PHYS_ADDR 0x11600000
#define SSI1_PHYS_ADDR 0x11680000
#define SYS_PHYS_ADDR 0x11900000
#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
......@@ -730,8 +731,6 @@ enum soc_au1200_ints {
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define USBH_PHYS_ADDR 0x10100000
#define PCI_PHYS_ADDR 0x14005000
#define GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000
#define PCI_MEM_PHYS_ADDR 0x400000000ULL
#define PCI_IO_PHYS_ADDR 0x500000000ULL
#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
......@@ -750,8 +749,6 @@ enum soc_au1200_ints {
#define IRDA_PHYS_ADDR 0x10300000
#define SSI0_PHYS_ADDR 0x11600000
#define SSI1_PHYS_ADDR 0x11680000
#define GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000
#define LCD_PHYS_ADDR 0x15000000
#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
......@@ -765,8 +762,6 @@ enum soc_au1200_ints {
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define USBH_PHYS_ADDR 0x14020000
#define PCI_PHYS_ADDR 0x14005000
#define GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000
#define PE_PHYS_ADDR 0x14008000
#define PSC0_PHYS_ADDR 0x11A00000
#define PSC1_PHYS_ADDR 0x11B00000
......@@ -790,8 +785,6 @@ enum soc_au1200_ints {
#define CIM_PHYS_ADDR 0x14004000
#define USBM_PHYS_ADDR 0x14020000
#define USBH_PHYS_ADDR 0x14020100
#define GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000
#define PSC0_PHYS_ADDR 0x11A00000
#define PSC1_PHYS_ADDR 0x11B00000
#define LCD_PHYS_ADDR 0x15000000
......@@ -1359,22 +1352,6 @@ enum soc_au1200_ints {
#define SYS_PINFUNC_S1B (1 << 2)
#endif
#define SYS_TRIOUTRD 0xB1900100
#define SYS_TRIOUTCLR 0xB1900100
#define SYS_OUTPUTRD 0xB1900108
#define SYS_OUTPUTSET 0xB1900108
#define SYS_OUTPUTCLR 0xB190010C
#define SYS_PINSTATERD 0xB1900110
#define SYS_PININPUTEN 0xB1900110
/* GPIO2, Au1500, Au1550 only */
#define GPIO2_BASE 0xB1700000
#define GPIO2_DIR (GPIO2_BASE + 0)
#define GPIO2_OUTPUT (GPIO2_BASE + 8)
#define GPIO2_PINSTATE (GPIO2_BASE + 0xC)
#define GPIO2_INTENABLE (GPIO2_BASE + 0x10)
#define GPIO2_ENABLE (GPIO2_BASE + 0x14)
/* Power Management */
#define SYS_SCRATCH0 0xB1900018
#define SYS_SCRATCH1 0xB190001C
......
......@@ -24,6 +24,22 @@
#define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off))
/* GPIO1 registers within SYS_ area */
#define SYS_TRIOUTRD 0x100
#define SYS_TRIOUTCLR 0x100
#define SYS_OUTPUTRD 0x108
#define SYS_OUTPUTSET 0x108
#define SYS_OUTPUTCLR 0x10C
#define SYS_PINSTATERD 0x110
#define SYS_PININPUTEN 0x110
/* register offsets within GPIO2 block */
#define GPIO2_DIR 0x00
#define GPIO2_OUTPUT 0x08
#define GPIO2_PINSTATE 0x0C
#define GPIO2_INTENABLE 0x10
#define GPIO2_ENABLE 0x14
struct gpio;
static inline int au1000_gpio1_to_irq(int gpio)
......@@ -201,23 +217,26 @@ static inline int au1200_irq_to_gpio(int irq)
*/
static inline void alchemy_gpio1_set_value(int gpio, int v)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR;
au_writel(mask, r);
au_sync();
__raw_writel(mask, base + r);
wmb();
}
static inline int alchemy_gpio1_get_value(int gpio)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
return au_readl(SYS_PINSTATERD) & mask;
return __raw_readl(base + SYS_PINSTATERD) & mask;
}
static inline int alchemy_gpio1_direction_input(int gpio)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
au_writel(mask, SYS_TRIOUTCLR);
au_sync();
__raw_writel(mask, base + SYS_TRIOUTCLR);
wmb();
return 0;
}
......@@ -258,27 +277,31 @@ static inline int alchemy_gpio1_to_irq(int gpio)
*/
static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE);
unsigned long d = au_readl(GPIO2_DIR);
unsigned long d = __raw_readl(base + GPIO2_DIR);
if (to_out)
d |= mask;
else
d &= ~mask;
au_writel(d, GPIO2_DIR);
au_sync();
__raw_writel(d, base + GPIO2_DIR);
wmb();
}
static inline void alchemy_gpio2_set_value(int gpio, int v)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
unsigned long mask;
mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE);
au_writel(mask, GPIO2_OUTPUT);
au_sync();
__raw_writel(mask, base + GPIO2_OUTPUT);
wmb();
}
static inline int alchemy_gpio2_get_value(int gpio)
{
return au_readl(GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE));
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
return __raw_readl(base + GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE));
}
static inline int alchemy_gpio2_direction_input(int gpio)
......@@ -330,21 +353,23 @@ static inline int alchemy_gpio2_to_irq(int gpio)
*/
static inline void alchemy_gpio1_input_enable(void)
{
au_writel(0, SYS_PININPUTEN); /* the write op is key */
au_sync();
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
__raw_writel(0, base + SYS_PININPUTEN); /* the write op is key */
wmb();
}
/* GPIO2 shared interrupts and control */
static inline void __alchemy_gpio2_mod_int(int gpio2, int en)
{
unsigned long r = au_readl(GPIO2_INTENABLE);
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
unsigned long r = __raw_readl(base + GPIO2_INTENABLE);
if (en)
r |= 1 << gpio2;
else
r &= ~(1 << gpio2);
au_writel(r, GPIO2_INTENABLE);
au_sync();
__raw_writel(r, base + GPIO2_INTENABLE);
wmb();
}
/**
......@@ -419,10 +444,11 @@ static inline void alchemy_gpio2_disable_int(int gpio2)
*/
static inline void alchemy_gpio2_enable(void)
{
au_writel(3, GPIO2_ENABLE); /* reset, clock enabled */
au_sync();
au_writel(1, GPIO2_ENABLE); /* clock enabled */
au_sync();
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
__raw_writel(3, base + GPIO2_ENABLE); /* reset, clock enabled */
wmb();
__raw_writel(1, base + GPIO2_ENABLE); /* clock enabled */
wmb();
}
/**
......@@ -432,8 +458,9 @@ static inline void alchemy_gpio2_enable(void)
*/
static inline void alchemy_gpio2_disable(void)
{
au_writel(2, GPIO2_ENABLE); /* reset, clock disabled */
au_sync();
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
__raw_writel(2, base + GPIO2_ENABLE); /* reset, clock disabled */
wmb();
}
/**********************************************************************/
......
......@@ -10,6 +10,7 @@
*/
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
......@@ -470,7 +471,7 @@ static int __init au1xxx_nand_init(void)
#ifdef CONFIG_MIPS_PB1550
/* set gpio206 high */
au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR);
gpio_direction_input(206);
boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
......
......@@ -66,6 +66,7 @@ static struct {
int default_ticks;
unsigned long inuse;
unsigned gpio;
int gstate;
} mtx1_wdt_device;
static void mtx1_wdt_trigger(unsigned long unused)
......@@ -75,13 +76,13 @@ static void mtx1_wdt_trigger(unsigned long unused)
spin_lock(&mtx1_wdt_device.lock);
if (mtx1_wdt_device.running)
ticks--;
/*
* toggle GPIO2_15
*/
tmp = au_readl(GPIO2_DIR);
tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) |
((~tmp) & (1 << mtx1_wdt_device.gpio));
au_writel(tmp, GPIO2_DIR);
/* toggle wdt gpio */
mtx1_wdt_device.gstate = ~mtx1_wdt_device.gstate;
if (mtx1_wdt_device.gstate)
gpio_direction_output(mtx1_wdt_device.gpio, 1);
else
gpio_direction_input(mtx1_wdt_device.gpio);
if (mtx1_wdt_device.queue && ticks)
mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
......@@ -103,7 +104,8 @@ static void mtx1_wdt_start(void)
spin_lock_irqsave(&mtx1_wdt_device.lock, flags);
if (!mtx1_wdt_device.queue) {
mtx1_wdt_device.queue = 1;
gpio_set_value(mtx1_wdt_device.gpio, 1);
mtx1_wdt_device.gstate = 1;
gpio_direction_output(mtx1_wdt_device.gpio, 1);
mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
}
mtx1_wdt_device.running++;
......@@ -117,7 +119,8 @@ static int mtx1_wdt_stop(void)
spin_lock_irqsave(&mtx1_wdt_device.lock, flags);
if (mtx1_wdt_device.queue) {
mtx1_wdt_device.queue = 0;
gpio_set_value(mtx1_wdt_device.gpio, 0);
mtx1_wdt_device.gstate = 0;
gpio_direction_output(mtx1_wdt_device.gpio, 0);
}
ticks = mtx1_wdt_device.default_ticks;
spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment