ARM: plat-stmp: remove plat
Now that both users of plat-stmp have been deleted in previous patches, delete the platform, too. Signed-off-by: Wolfram Sang <w.sang@pengutronix.de> Acked-by: Shawn Guo <shawn.guo@freescale.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
f295dc6874
commit
041f10d46f
|
@ -378,16 +378,6 @@ config ARCH_MXS
|
||||||
help
|
help
|
||||||
Support for Freescale MXS-based family of processors
|
Support for Freescale MXS-based family of processors
|
||||||
|
|
||||||
config ARCH_STMP3XXX
|
|
||||||
bool "Freescale STMP3xxx"
|
|
||||||
select CPU_ARM926T
|
|
||||||
select CLKDEV_LOOKUP
|
|
||||||
select ARCH_REQUIRE_GPIOLIB
|
|
||||||
select GENERIC_CLOCKEVENTS
|
|
||||||
select USB_ARCH_HAS_EHCI
|
|
||||||
help
|
|
||||||
Support for systems based on the Freescale 3xxx CPUs.
|
|
||||||
|
|
||||||
config ARCH_NETX
|
config ARCH_NETX
|
||||||
bool "Hilscher NetX based"
|
bool "Hilscher NetX based"
|
||||||
select CPU_ARM926T
|
select CPU_ARM926T
|
||||||
|
@ -1005,8 +995,6 @@ source "arch/arm/mach-exynos4/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/mach-shmobile/Kconfig"
|
source "arch/arm/mach-shmobile/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/plat-stmp3xxx/Kconfig"
|
|
||||||
|
|
||||||
source "arch/arm/mach-tegra/Kconfig"
|
source "arch/arm/mach-tegra/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/mach-u300/Kconfig"
|
source "arch/arm/mach-u300/Kconfig"
|
||||||
|
|
|
@ -205,7 +205,6 @@ machine-$(CONFIG_MACH_SPEAR600) := spear6xx
|
||||||
plat-$(CONFIG_ARCH_MXC) := mxc
|
plat-$(CONFIG_ARCH_MXC) := mxc
|
||||||
plat-$(CONFIG_ARCH_OMAP) := omap
|
plat-$(CONFIG_ARCH_OMAP) := omap
|
||||||
plat-$(CONFIG_ARCH_S3C64XX) := samsung
|
plat-$(CONFIG_ARCH_S3C64XX) := samsung
|
||||||
plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx
|
|
||||||
plat-$(CONFIG_ARCH_TCC_926) := tcc
|
plat-$(CONFIG_ARCH_TCC_926) := tcc
|
||||||
plat-$(CONFIG_PLAT_IOP) := iop
|
plat-$(CONFIG_PLAT_IOP) := iop
|
||||||
plat-$(CONFIG_PLAT_NOMADIK) := nomadik
|
plat-$(CONFIG_PLAT_NOMADIK) := nomadik
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
if ARCH_STMP3XXX
|
|
||||||
|
|
||||||
menu "Freescale STMP3xxx implementations"
|
|
||||||
|
|
||||||
endmenu
|
|
||||||
|
|
||||||
endif
|
|
|
@ -1,5 +0,0 @@
|
||||||
#
|
|
||||||
# Makefile for the linux kernel.
|
|
||||||
#
|
|
||||||
# Object file lists.
|
|
||||||
obj-y += core.o timer.o irq.o dma.o clock.o pinmux.o devices.o
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,61 +0,0 @@
|
||||||
/*
|
|
||||||
* Clock control driver for Freescale STMP37XX/STMP378X - internal header file
|
|
||||||
*
|
|
||||||
* Author: Vitaly Wool <vital@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ARCH_ARM_STMX3XXX_CLOCK_H__
|
|
||||||
#define __ARCH_ARM_STMX3XXX_CLOCK_H__
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
|
||||||
|
|
||||||
struct clk_ops {
|
|
||||||
int (*enable) (struct clk *);
|
|
||||||
int (*disable) (struct clk *);
|
|
||||||
long (*get_rate) (struct clk *);
|
|
||||||
long (*round_rate) (struct clk *, u32);
|
|
||||||
int (*set_rate) (struct clk *, u32);
|
|
||||||
int (*set_parent) (struct clk *, struct clk *);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clk {
|
|
||||||
struct clk *parent;
|
|
||||||
u32 rate;
|
|
||||||
u32 flags;
|
|
||||||
u8 scale_shift;
|
|
||||||
u8 enable_shift;
|
|
||||||
u8 bypass_shift;
|
|
||||||
u8 busy_bit;
|
|
||||||
s8 usage;
|
|
||||||
int enable_wait;
|
|
||||||
int enable_negate;
|
|
||||||
u32 saved_div;
|
|
||||||
void __iomem *enable_reg;
|
|
||||||
void __iomem *scale_reg;
|
|
||||||
void __iomem *bypass_reg;
|
|
||||||
void __iomem *busy_reg;
|
|
||||||
struct clk_ops *ops;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLER__ */
|
|
||||||
|
|
||||||
/* Flags */
|
|
||||||
#define RATE_PROPAGATES (1<<0)
|
|
||||||
#define NEEDS_INITIALIZATION (1<<1)
|
|
||||||
#define PARENT_SET_RATE (1<<2)
|
|
||||||
#define FIXED_RATE (1<<3)
|
|
||||||
#define ENABLED (1<<4)
|
|
||||||
#define NEEDS_SET_PARENT (1<<5)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,128 +0,0 @@
|
||||||
/*
|
|
||||||
* Freescale STMP37XX/STMP378X core routines
|
|
||||||
*
|
|
||||||
* Embedded Alley Solutions, Inc <source@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
|
|
||||||
#include <mach/stmp3xxx.h>
|
|
||||||
#include <mach/platform.h>
|
|
||||||
#include <mach/dma.h>
|
|
||||||
#include <mach/regs-clkctrl.h>
|
|
||||||
|
|
||||||
static int __stmp3xxx_reset_block(void __iomem *hwreg, int just_enable)
|
|
||||||
{
|
|
||||||
u32 c;
|
|
||||||
int timeout;
|
|
||||||
|
|
||||||
/* the process of software reset of IP block is done
|
|
||||||
in several steps:
|
|
||||||
|
|
||||||
- clear SFTRST and wait for block is enabled;
|
|
||||||
- clear clock gating (CLKGATE bit);
|
|
||||||
- set the SFTRST again and wait for block is in reset;
|
|
||||||
- clear SFTRST and wait for reset completion.
|
|
||||||
*/
|
|
||||||
c = __raw_readl(hwreg);
|
|
||||||
c &= ~(1<<31); /* clear SFTRST */
|
|
||||||
__raw_writel(c, hwreg);
|
|
||||||
for (timeout = 1000000; timeout > 0; timeout--)
|
|
||||||
/* still in SFTRST state ? */
|
|
||||||
if ((__raw_readl(hwreg) & (1<<31)) == 0)
|
|
||||||
break;
|
|
||||||
if (timeout <= 0) {
|
|
||||||
printk(KERN_ERR"%s(%p): timeout when enabling\n",
|
|
||||||
__func__, hwreg);
|
|
||||||
return -ETIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = __raw_readl(hwreg);
|
|
||||||
c &= ~(1<<30); /* clear CLKGATE */
|
|
||||||
__raw_writel(c, hwreg);
|
|
||||||
|
|
||||||
if (!just_enable) {
|
|
||||||
c = __raw_readl(hwreg);
|
|
||||||
c |= (1<<31); /* now again set SFTRST */
|
|
||||||
__raw_writel(c, hwreg);
|
|
||||||
for (timeout = 1000000; timeout > 0; timeout--)
|
|
||||||
/* poll until CLKGATE set */
|
|
||||||
if (__raw_readl(hwreg) & (1<<30))
|
|
||||||
break;
|
|
||||||
if (timeout <= 0) {
|
|
||||||
printk(KERN_ERR"%s(%p): timeout when resetting\n",
|
|
||||||
__func__, hwreg);
|
|
||||||
return -ETIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = __raw_readl(hwreg);
|
|
||||||
c &= ~(1<<31); /* clear SFTRST */
|
|
||||||
__raw_writel(c, hwreg);
|
|
||||||
for (timeout = 1000000; timeout > 0; timeout--)
|
|
||||||
/* still in SFTRST state ? */
|
|
||||||
if ((__raw_readl(hwreg) & (1<<31)) == 0)
|
|
||||||
break;
|
|
||||||
if (timeout <= 0) {
|
|
||||||
printk(KERN_ERR"%s(%p): timeout when enabling "
|
|
||||||
"after reset\n", __func__, hwreg);
|
|
||||||
return -ETIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = __raw_readl(hwreg);
|
|
||||||
c &= ~(1<<30); /* clear CLKGATE */
|
|
||||||
__raw_writel(c, hwreg);
|
|
||||||
}
|
|
||||||
for (timeout = 1000000; timeout > 0; timeout--)
|
|
||||||
/* still in SFTRST state ? */
|
|
||||||
if ((__raw_readl(hwreg) & (1<<30)) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (timeout <= 0) {
|
|
||||||
printk(KERN_ERR"%s(%p): timeout when unclockgating\n",
|
|
||||||
__func__, hwreg);
|
|
||||||
return -ETIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable)
|
|
||||||
{
|
|
||||||
int try = 10;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
while (try--) {
|
|
||||||
r = __stmp3xxx_reset_block(hwreg, just_enable);
|
|
||||||
if (!r)
|
|
||||||
break;
|
|
||||||
pr_debug("%s: try %d failed\n", __func__, 10 - try);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_reset_block);
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_dbguart = {
|
|
||||||
.name = "stmp3xxx-dbguart",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
void __init stmp3xxx_init(void)
|
|
||||||
{
|
|
||||||
/* Turn off auto-slow and other tricks */
|
|
||||||
stmp3xxx_clearl(0x7f00000, REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS);
|
|
||||||
|
|
||||||
stmp3xxx_dma_init();
|
|
||||||
}
|
|
|
@ -1,389 +0,0 @@
|
||||||
/*
|
|
||||||
* Freescale STMP37XX/STMP378X platform devices
|
|
||||||
*
|
|
||||||
* Embedded Alley Solutions, Inc <source@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/dma-mapping.h>
|
|
||||||
|
|
||||||
#include <mach/dma.h>
|
|
||||||
#include <mach/platform.h>
|
|
||||||
#include <mach/stmp3xxx.h>
|
|
||||||
#include <mach/regs-lcdif.h>
|
|
||||||
#include <mach/regs-uartapp.h>
|
|
||||||
#include <mach/regs-gpmi.h>
|
|
||||||
#include <mach/regs-usbctrl.h>
|
|
||||||
#include <mach/regs-ssp.h>
|
|
||||||
#include <mach/regs-rtc.h>
|
|
||||||
|
|
||||||
static u64 common_dmamask = DMA_BIT_MASK(32);
|
|
||||||
|
|
||||||
static struct resource appuart_resources[] = {
|
|
||||||
{
|
|
||||||
.start = IRQ_UARTAPP_INTERNAL,
|
|
||||||
.end = IRQ_UARTAPP_INTERNAL,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
}, {
|
|
||||||
.start = IRQ_UARTAPP_RX_DMA,
|
|
||||||
.end = IRQ_UARTAPP_RX_DMA,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
}, {
|
|
||||||
.start = IRQ_UARTAPP_TX_DMA,
|
|
||||||
.end = IRQ_UARTAPP_TX_DMA,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
}, {
|
|
||||||
.start = REGS_UARTAPP1_PHYS,
|
|
||||||
.end = REGS_UARTAPP1_PHYS + REGS_UARTAPP_SIZE,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
}, {
|
|
||||||
/* Rx DMA channel */
|
|
||||||
.start = STMP3XXX_DMA(6, STMP3XXX_BUS_APBX),
|
|
||||||
.end = STMP3XXX_DMA(6, STMP3XXX_BUS_APBX),
|
|
||||||
.flags = IORESOURCE_DMA,
|
|
||||||
}, {
|
|
||||||
/* Tx DMA channel */
|
|
||||||
.start = STMP3XXX_DMA(7, STMP3XXX_BUS_APBX),
|
|
||||||
.end = STMP3XXX_DMA(7, STMP3XXX_BUS_APBX),
|
|
||||||
.flags = IORESOURCE_DMA,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_appuart = {
|
|
||||||
.name = "stmp3xxx-appuart",
|
|
||||||
.id = 0,
|
|
||||||
.resource = appuart_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(appuart_resources),
|
|
||||||
.dev = {
|
|
||||||
.dma_mask = &common_dmamask,
|
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_watchdog = {
|
|
||||||
.name = "stmp3xxx_wdt",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource ts_resource[] = {
|
|
||||||
{
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
.start = IRQ_TOUCH_DETECT,
|
|
||||||
.end = IRQ_TOUCH_DETECT,
|
|
||||||
}, {
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
.start = IRQ_LRADC_CH5,
|
|
||||||
.end = IRQ_LRADC_CH5,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_touchscreen = {
|
|
||||||
.name = "stmp3xxx_ts",
|
|
||||||
.id = -1,
|
|
||||||
.resource = ts_resource,
|
|
||||||
.num_resources = ARRAY_SIZE(ts_resource),
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Keypad device
|
|
||||||
*/
|
|
||||||
struct platform_device stmp3xxx_keyboard = {
|
|
||||||
.name = "stmp3xxx-keyboard",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource gpmi_resources[] = {
|
|
||||||
{
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
.start = REGS_GPMI_PHYS,
|
|
||||||
.end = REGS_GPMI_PHYS + REGS_GPMI_SIZE,
|
|
||||||
}, {
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
.start = IRQ_GPMI_DMA,
|
|
||||||
.end = IRQ_GPMI_DMA,
|
|
||||||
}, {
|
|
||||||
.flags = IORESOURCE_DMA,
|
|
||||||
.start = STMP3XXX_DMA(4, STMP3XXX_BUS_APBH),
|
|
||||||
.end = STMP3XXX_DMA(8, STMP3XXX_BUS_APBH),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_gpmi = {
|
|
||||||
.name = "gpmi",
|
|
||||||
.id = -1,
|
|
||||||
.dev = {
|
|
||||||
.dma_mask = &common_dmamask,
|
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
|
||||||
},
|
|
||||||
.resource = gpmi_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(gpmi_resources),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource mmc1_resource[] = {
|
|
||||||
{
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
.start = REGS_SSP1_PHYS,
|
|
||||||
.end = REGS_SSP1_PHYS + REGS_SSP_SIZE,
|
|
||||||
}, {
|
|
||||||
.flags = IORESOURCE_DMA,
|
|
||||||
.start = STMP3XXX_DMA(1, STMP3XXX_BUS_APBH),
|
|
||||||
.end = STMP3XXX_DMA(1, STMP3XXX_BUS_APBH),
|
|
||||||
}, {
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
.start = IRQ_SSP1_DMA,
|
|
||||||
.end = IRQ_SSP1_DMA,
|
|
||||||
}, {
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
.start = IRQ_SSP_ERROR,
|
|
||||||
.end = IRQ_SSP_ERROR,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_mmc = {
|
|
||||||
.name = "stmp3xxx-mmc",
|
|
||||||
.id = 1,
|
|
||||||
.dev = {
|
|
||||||
.dma_mask = &common_dmamask,
|
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
|
||||||
},
|
|
||||||
.resource = mmc1_resource,
|
|
||||||
.num_resources = ARRAY_SIZE(mmc1_resource),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource usb_resources[] = {
|
|
||||||
{
|
|
||||||
.start = REGS_USBCTRL_PHYS,
|
|
||||||
.end = REGS_USBCTRL_PHYS + SZ_4K,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
}, {
|
|
||||||
.start = IRQ_USB_CTRL,
|
|
||||||
.end = IRQ_USB_CTRL,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_udc = {
|
|
||||||
.name = "fsl-usb2-udc",
|
|
||||||
.id = -1,
|
|
||||||
.dev = {
|
|
||||||
.dma_mask = &common_dmamask,
|
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
|
||||||
},
|
|
||||||
.resource = usb_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(usb_resources),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_ehci = {
|
|
||||||
.name = "fsl-ehci",
|
|
||||||
.id = -1,
|
|
||||||
.dev = {
|
|
||||||
.dma_mask = &common_dmamask,
|
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
|
||||||
},
|
|
||||||
.resource = usb_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(usb_resources),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource rtc_resources[] = {
|
|
||||||
{
|
|
||||||
.start = REGS_RTC_PHYS,
|
|
||||||
.end = REGS_RTC_PHYS + REGS_RTC_SIZE,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
}, {
|
|
||||||
.start = IRQ_RTC_ALARM,
|
|
||||||
.end = IRQ_RTC_ALARM,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
}, {
|
|
||||||
.start = IRQ_RTC_1MSEC,
|
|
||||||
.end = IRQ_RTC_1MSEC,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_rtc = {
|
|
||||||
.name = "stmp3xxx-rtc",
|
|
||||||
.id = -1,
|
|
||||||
.resource = rtc_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource ssp1_resources[] = {
|
|
||||||
{
|
|
||||||
.start = REGS_SSP1_PHYS,
|
|
||||||
.end = REGS_SSP1_PHYS + REGS_SSP_SIZE,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
}, {
|
|
||||||
.start = IRQ_SSP1_DMA,
|
|
||||||
.end = IRQ_SSP1_DMA,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
}, {
|
|
||||||
.start = STMP3XXX_DMA(1, STMP3XXX_BUS_APBH),
|
|
||||||
.end = STMP3XXX_DMA(1, STMP3XXX_BUS_APBH),
|
|
||||||
.flags = IORESOURCE_DMA,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource ssp2_resources[] = {
|
|
||||||
{
|
|
||||||
.start = REGS_SSP2_PHYS,
|
|
||||||
.end = REGS_SSP2_PHYS + REGS_SSP_SIZE,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
}, {
|
|
||||||
.start = IRQ_SSP2_DMA,
|
|
||||||
.end = IRQ_SSP2_DMA,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
}, {
|
|
||||||
.start = STMP3XXX_DMA(2, STMP3XXX_BUS_APBH),
|
|
||||||
.end = STMP3XXX_DMA(2, STMP3XXX_BUS_APBH),
|
|
||||||
.flags = IORESOURCE_DMA,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_spi1 = {
|
|
||||||
.name = "stmp3xxx_ssp",
|
|
||||||
.id = 1,
|
|
||||||
.dev = {
|
|
||||||
.dma_mask = &common_dmamask,
|
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
|
||||||
},
|
|
||||||
.resource = ssp1_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(ssp1_resources),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_spi2 = {
|
|
||||||
.name = "stmp3xxx_ssp",
|
|
||||||
.id = 2,
|
|
||||||
.dev = {
|
|
||||||
.dma_mask = &common_dmamask,
|
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
|
||||||
},
|
|
||||||
.resource = ssp2_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(ssp2_resources),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource fb_resource[] = {
|
|
||||||
{
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
.start = IRQ_LCDIF_DMA,
|
|
||||||
.end = IRQ_LCDIF_DMA,
|
|
||||||
}, {
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
.start = IRQ_LCDIF_ERROR,
|
|
||||||
.end = IRQ_LCDIF_ERROR,
|
|
||||||
}, {
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
.start = REGS_LCDIF_PHYS,
|
|
||||||
.end = REGS_LCDIF_PHYS + REGS_LCDIF_SIZE,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_framebuffer = {
|
|
||||||
.name = "stmp3xxx-fb",
|
|
||||||
.id = -1,
|
|
||||||
.dev = {
|
|
||||||
.dma_mask = &common_dmamask,
|
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
|
||||||
},
|
|
||||||
.num_resources = ARRAY_SIZE(fb_resource),
|
|
||||||
.resource = fb_resource,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CMDLINE_DEVICE_CHOOSE(name, dev1, dev2) \
|
|
||||||
static char *cmdline_device_##name; \
|
|
||||||
static int cmdline_device_##name##_setup(char *dev) \
|
|
||||||
{ \
|
|
||||||
cmdline_device_##name = dev + 1; \
|
|
||||||
return 0; \
|
|
||||||
} \
|
|
||||||
__setup(#name, cmdline_device_##name##_setup); \
|
|
||||||
int stmp3xxx_##name##_device_register(void) \
|
|
||||||
{ \
|
|
||||||
struct platform_device *d = NULL; \
|
|
||||||
if (!cmdline_device_##name || \
|
|
||||||
!strcmp(cmdline_device_##name, #dev1)) \
|
|
||||||
d = &stmp3xxx_##dev1; \
|
|
||||||
else if (!strcmp(cmdline_device_##name, #dev2)) \
|
|
||||||
d = &stmp3xxx_##dev2; \
|
|
||||||
else \
|
|
||||||
printk(KERN_ERR"Unknown %s assignment '%s'.\n", \
|
|
||||||
#name, cmdline_device_##name); \
|
|
||||||
return d ? platform_device_register(d) : -ENOENT; \
|
|
||||||
}
|
|
||||||
|
|
||||||
CMDLINE_DEVICE_CHOOSE(ssp1, mmc, spi1)
|
|
||||||
CMDLINE_DEVICE_CHOOSE(ssp2, gpmi, spi2)
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_backlight = {
|
|
||||||
.name = "stmp3xxx-bl",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_rotdec = {
|
|
||||||
.name = "stmp3xxx-rotdec",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_persistent = {
|
|
||||||
.name = "stmp3xxx-persistent",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_dcp_bootstream = {
|
|
||||||
.name = "stmp3xxx-dcpboot",
|
|
||||||
.id = -1,
|
|
||||||
.dev = {
|
|
||||||
.dma_mask = &common_dmamask,
|
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource dcp_resources[] = {
|
|
||||||
{
|
|
||||||
.start = IRQ_DCP_VMI,
|
|
||||||
.end = IRQ_DCP_VMI,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
}, {
|
|
||||||
.start = IRQ_DCP,
|
|
||||||
.end = IRQ_DCP,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_dcp = {
|
|
||||||
.name = "stmp3xxx-dcp",
|
|
||||||
.id = -1,
|
|
||||||
.resource = dcp_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(dcp_resources),
|
|
||||||
.dev = {
|
|
||||||
.dma_mask = &common_dmamask,
|
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource battery_resource[] = {
|
|
||||||
{
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
.start = IRQ_VDD5V,
|
|
||||||
.end = IRQ_VDD5V,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct platform_device stmp3xxx_battery = {
|
|
||||||
.name = "stmp3xxx-battery",
|
|
||||||
.resource = battery_resource,
|
|
||||||
.num_resources = ARRAY_SIZE(battery_resource),
|
|
||||||
};
|
|
|
@ -1,464 +0,0 @@
|
||||||
/*
|
|
||||||
* DMA helper routines for Freescale STMP37XX/STMP378X
|
|
||||||
*
|
|
||||||
* Author: dmitry pervushin <dpervushin@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/dmapool.h>
|
|
||||||
#include <linux/sysdev.h>
|
|
||||||
#include <linux/cpufreq.h>
|
|
||||||
|
|
||||||
#include <asm/page.h>
|
|
||||||
|
|
||||||
#include <mach/platform.h>
|
|
||||||
#include <mach/dma.h>
|
|
||||||
#include <mach/regs-apbx.h>
|
|
||||||
#include <mach/regs-apbh.h>
|
|
||||||
|
|
||||||
static const size_t pool_item_size = sizeof(struct stmp3xxx_dma_command);
|
|
||||||
static const size_t pool_alignment = 8;
|
|
||||||
static struct stmp3xxx_dma_user {
|
|
||||||
void *pool;
|
|
||||||
int inuse;
|
|
||||||
const char *name;
|
|
||||||
} channels[MAX_DMA_CHANNELS];
|
|
||||||
|
|
||||||
#define IS_VALID_CHANNEL(ch) ((ch) >= 0 && (ch) < MAX_DMA_CHANNELS)
|
|
||||||
#define IS_USED(ch) (channels[ch].inuse)
|
|
||||||
|
|
||||||
int stmp3xxx_dma_request(int ch, struct device *dev, const char *name)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_dma_user *user;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
user = channels + ch;
|
|
||||||
if (!IS_VALID_CHANNEL(ch)) {
|
|
||||||
err = -ENODEV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (IS_USED(ch)) {
|
|
||||||
err = -EBUSY;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* Create a pool to allocate dma commands from */
|
|
||||||
user->pool = dma_pool_create(name, dev, pool_item_size,
|
|
||||||
pool_alignment, PAGE_SIZE);
|
|
||||||
if (user->pool == NULL) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
user->name = name;
|
|
||||||
user->inuse++;
|
|
||||||
out:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_dma_request);
|
|
||||||
|
|
||||||
int stmp3xxx_dma_release(int ch)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_dma_user *user = channels + ch;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
if (!IS_VALID_CHANNEL(ch)) {
|
|
||||||
err = -ENODEV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (!IS_USED(ch)) {
|
|
||||||
err = -EBUSY;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
BUG_ON(user->pool == NULL);
|
|
||||||
dma_pool_destroy(user->pool);
|
|
||||||
user->inuse--;
|
|
||||||
out:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_dma_release);
|
|
||||||
|
|
||||||
int stmp3xxx_dma_read_semaphore(int channel)
|
|
||||||
{
|
|
||||||
int sem = -1;
|
|
||||||
|
|
||||||
switch (STMP3XXX_DMA_BUS(channel)) {
|
|
||||||
case STMP3XXX_BUS_APBH:
|
|
||||||
sem = __raw_readl(REGS_APBH_BASE + HW_APBH_CHn_SEMA +
|
|
||||||
STMP3XXX_DMA_CHANNEL(channel) * 0x70);
|
|
||||||
sem &= BM_APBH_CHn_SEMA_PHORE;
|
|
||||||
sem >>= BP_APBH_CHn_SEMA_PHORE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STMP3XXX_BUS_APBX:
|
|
||||||
sem = __raw_readl(REGS_APBX_BASE + HW_APBX_CHn_SEMA +
|
|
||||||
STMP3XXX_DMA_CHANNEL(channel) * 0x70);
|
|
||||||
sem &= BM_APBX_CHn_SEMA_PHORE;
|
|
||||||
sem >>= BP_APBX_CHn_SEMA_PHORE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
return sem;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_dma_read_semaphore);
|
|
||||||
|
|
||||||
int stmp3xxx_dma_allocate_command(int channel,
|
|
||||||
struct stmp3xxx_dma_descriptor *descriptor)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_dma_user *user = channels + channel;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
if (!IS_VALID_CHANNEL(channel)) {
|
|
||||||
err = -ENODEV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (!IS_USED(channel)) {
|
|
||||||
err = -EBUSY;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (descriptor == NULL) {
|
|
||||||
err = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for a command from the buffer */
|
|
||||||
descriptor->command =
|
|
||||||
dma_pool_alloc(user->pool, GFP_KERNEL, &descriptor->handle);
|
|
||||||
|
|
||||||
/* Check it worked */
|
|
||||||
if (!descriptor->command) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(descriptor->command, 0, pool_item_size);
|
|
||||||
out:
|
|
||||||
WARN_ON(err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_dma_allocate_command);
|
|
||||||
|
|
||||||
int stmp3xxx_dma_free_command(int channel,
|
|
||||||
struct stmp3xxx_dma_descriptor *descriptor)
|
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
if (!IS_VALID_CHANNEL(channel)) {
|
|
||||||
err = -ENODEV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (!IS_USED(channel)) {
|
|
||||||
err = -EBUSY;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the command memory to the pool */
|
|
||||||
dma_pool_free(channels[channel].pool, descriptor->command,
|
|
||||||
descriptor->handle);
|
|
||||||
|
|
||||||
/* Initialise descriptor so we're not tempted to use it */
|
|
||||||
descriptor->command = NULL;
|
|
||||||
descriptor->handle = 0;
|
|
||||||
descriptor->virtual_buf_ptr = NULL;
|
|
||||||
descriptor->next_descr = NULL;
|
|
||||||
|
|
||||||
WARN_ON(err);
|
|
||||||
out:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_dma_free_command);
|
|
||||||
|
|
||||||
void stmp3xxx_dma_go(int channel,
|
|
||||||
struct stmp3xxx_dma_descriptor *head, u32 semaphore)
|
|
||||||
{
|
|
||||||
int ch = STMP3XXX_DMA_CHANNEL(channel);
|
|
||||||
void __iomem *c, *s;
|
|
||||||
|
|
||||||
switch (STMP3XXX_DMA_BUS(channel)) {
|
|
||||||
case STMP3XXX_BUS_APBH:
|
|
||||||
c = REGS_APBH_BASE + HW_APBH_CHn_NXTCMDAR + 0x70 * ch;
|
|
||||||
s = REGS_APBH_BASE + HW_APBH_CHn_SEMA + 0x70 * ch;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STMP3XXX_BUS_APBX:
|
|
||||||
c = REGS_APBX_BASE + HW_APBX_CHn_NXTCMDAR + 0x70 * ch;
|
|
||||||
s = REGS_APBX_BASE + HW_APBX_CHn_SEMA + 0x70 * ch;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set next command */
|
|
||||||
__raw_writel(head->handle, c);
|
|
||||||
/* Set counting semaphore (kicks off transfer). Assumes
|
|
||||||
peripheral has been set up correctly */
|
|
||||||
__raw_writel(semaphore, s);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_dma_go);
|
|
||||||
|
|
||||||
int stmp3xxx_dma_running(int channel)
|
|
||||||
{
|
|
||||||
switch (STMP3XXX_DMA_BUS(channel)) {
|
|
||||||
case STMP3XXX_BUS_APBH:
|
|
||||||
return (__raw_readl(REGS_APBH_BASE + HW_APBH_CHn_SEMA +
|
|
||||||
0x70 * STMP3XXX_DMA_CHANNEL(channel))) &
|
|
||||||
BM_APBH_CHn_SEMA_PHORE;
|
|
||||||
|
|
||||||
case STMP3XXX_BUS_APBX:
|
|
||||||
return (__raw_readl(REGS_APBX_BASE + HW_APBX_CHn_SEMA +
|
|
||||||
0x70 * STMP3XXX_DMA_CHANNEL(channel))) &
|
|
||||||
BM_APBX_CHn_SEMA_PHORE;
|
|
||||||
default:
|
|
||||||
BUG();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_dma_running);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Circular dma chain management
|
|
||||||
*/
|
|
||||||
void stmp3xxx_dma_free_chain(struct stmp37xx_circ_dma_chain *chain)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < chain->total_count; i++)
|
|
||||||
stmp3xxx_dma_free_command(
|
|
||||||
STMP3XXX_DMA(chain->channel, chain->bus),
|
|
||||||
&chain->chain[i]);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_dma_free_chain);
|
|
||||||
|
|
||||||
int stmp3xxx_dma_make_chain(int ch, struct stmp37xx_circ_dma_chain *chain,
|
|
||||||
struct stmp3xxx_dma_descriptor descriptors[],
|
|
||||||
unsigned items)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
if (items == 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
for (i = 0; i < items; i++) {
|
|
||||||
err = stmp3xxx_dma_allocate_command(ch, &descriptors[i]);
|
|
||||||
if (err) {
|
|
||||||
WARN_ON(err);
|
|
||||||
/*
|
|
||||||
* Couldn't allocate the whole chain.
|
|
||||||
* deallocate what has been allocated
|
|
||||||
*/
|
|
||||||
if (i) {
|
|
||||||
do {
|
|
||||||
stmp3xxx_dma_free_command(ch,
|
|
||||||
&descriptors
|
|
||||||
[i]);
|
|
||||||
} while (i-- > 0);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* link them! */
|
|
||||||
if (i > 0) {
|
|
||||||
descriptors[i - 1].next_descr = &descriptors[i];
|
|
||||||
descriptors[i - 1].command->next =
|
|
||||||
descriptors[i].handle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make list circular */
|
|
||||||
descriptors[items - 1].next_descr = &descriptors[0];
|
|
||||||
descriptors[items - 1].command->next = descriptors[0].handle;
|
|
||||||
|
|
||||||
chain->total_count = items;
|
|
||||||
chain->chain = descriptors;
|
|
||||||
chain->free_index = 0;
|
|
||||||
chain->active_index = 0;
|
|
||||||
chain->cooked_index = 0;
|
|
||||||
chain->free_count = items;
|
|
||||||
chain->active_count = 0;
|
|
||||||
chain->cooked_count = 0;
|
|
||||||
chain->bus = STMP3XXX_DMA_BUS(ch);
|
|
||||||
chain->channel = STMP3XXX_DMA_CHANNEL(ch);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_dma_make_chain);
|
|
||||||
|
|
||||||
void stmp37xx_circ_clear_chain(struct stmp37xx_circ_dma_chain *chain)
|
|
||||||
{
|
|
||||||
BUG_ON(stmp3xxx_dma_running(STMP3XXX_DMA(chain->channel, chain->bus)));
|
|
||||||
chain->free_index = 0;
|
|
||||||
chain->active_index = 0;
|
|
||||||
chain->cooked_index = 0;
|
|
||||||
chain->free_count = chain->total_count;
|
|
||||||
chain->active_count = 0;
|
|
||||||
chain->cooked_count = 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp37xx_circ_clear_chain);
|
|
||||||
|
|
||||||
void stmp37xx_circ_advance_free(struct stmp37xx_circ_dma_chain *chain,
|
|
||||||
unsigned count)
|
|
||||||
{
|
|
||||||
BUG_ON(chain->cooked_count < count);
|
|
||||||
|
|
||||||
chain->cooked_count -= count;
|
|
||||||
chain->cooked_index += count;
|
|
||||||
chain->cooked_index %= chain->total_count;
|
|
||||||
chain->free_count += count;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp37xx_circ_advance_free);
|
|
||||||
|
|
||||||
void stmp37xx_circ_advance_active(struct stmp37xx_circ_dma_chain *chain,
|
|
||||||
unsigned count)
|
|
||||||
{
|
|
||||||
void __iomem *c;
|
|
||||||
u32 mask_clr, mask;
|
|
||||||
BUG_ON(chain->free_count < count);
|
|
||||||
|
|
||||||
chain->free_count -= count;
|
|
||||||
chain->free_index += count;
|
|
||||||
chain->free_index %= chain->total_count;
|
|
||||||
chain->active_count += count;
|
|
||||||
|
|
||||||
switch (chain->bus) {
|
|
||||||
case STMP3XXX_BUS_APBH:
|
|
||||||
c = REGS_APBH_BASE + HW_APBH_CHn_SEMA + 0x70 * chain->channel;
|
|
||||||
mask_clr = BM_APBH_CHn_SEMA_INCREMENT_SEMA;
|
|
||||||
mask = BF(count, APBH_CHn_SEMA_INCREMENT_SEMA);
|
|
||||||
break;
|
|
||||||
case STMP3XXX_BUS_APBX:
|
|
||||||
c = REGS_APBX_BASE + HW_APBX_CHn_SEMA + 0x70 * chain->channel;
|
|
||||||
mask_clr = BM_APBX_CHn_SEMA_INCREMENT_SEMA;
|
|
||||||
mask = BF(count, APBX_CHn_SEMA_INCREMENT_SEMA);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BUG();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set counting semaphore (kicks off transfer). Assumes
|
|
||||||
peripheral has been set up correctly */
|
|
||||||
stmp3xxx_clearl(mask_clr, c);
|
|
||||||
stmp3xxx_setl(mask, c);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp37xx_circ_advance_active);
|
|
||||||
|
|
||||||
unsigned stmp37xx_circ_advance_cooked(struct stmp37xx_circ_dma_chain *chain)
|
|
||||||
{
|
|
||||||
unsigned cooked;
|
|
||||||
|
|
||||||
cooked = chain->active_count -
|
|
||||||
stmp3xxx_dma_read_semaphore(STMP3XXX_DMA(chain->channel, chain->bus));
|
|
||||||
|
|
||||||
chain->active_count -= cooked;
|
|
||||||
chain->active_index += cooked;
|
|
||||||
chain->active_index %= chain->total_count;
|
|
||||||
|
|
||||||
chain->cooked_count += cooked;
|
|
||||||
|
|
||||||
return cooked;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp37xx_circ_advance_cooked);
|
|
||||||
|
|
||||||
void stmp3xxx_dma_set_alt_target(int channel, int function)
|
|
||||||
{
|
|
||||||
#if defined(CONFIG_ARCH_STMP37XX)
|
|
||||||
unsigned bits = 4;
|
|
||||||
#elif defined(CONFIG_ARCH_STMP378X)
|
|
||||||
unsigned bits = 2;
|
|
||||||
#else
|
|
||||||
#error wrong arch
|
|
||||||
#endif
|
|
||||||
int shift = STMP3XXX_DMA_CHANNEL(channel) * bits;
|
|
||||||
unsigned mask = (1<<bits) - 1;
|
|
||||||
void __iomem *c;
|
|
||||||
|
|
||||||
BUG_ON(function < 0 || function >= (1<<bits));
|
|
||||||
pr_debug("%s: channel = %d, using mask %x, "
|
|
||||||
"shift = %d\n", __func__, channel, mask, shift);
|
|
||||||
|
|
||||||
switch (STMP3XXX_DMA_BUS(channel)) {
|
|
||||||
case STMP3XXX_BUS_APBH:
|
|
||||||
c = REGS_APBH_BASE + HW_APBH_DEVSEL;
|
|
||||||
break;
|
|
||||||
case STMP3XXX_BUS_APBX:
|
|
||||||
c = REGS_APBX_BASE + HW_APBX_DEVSEL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
stmp3xxx_clearl(mask << shift, c);
|
|
||||||
stmp3xxx_setl(mask << shift, c);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_dma_set_alt_target);
|
|
||||||
|
|
||||||
void stmp3xxx_dma_suspend(void)
|
|
||||||
{
|
|
||||||
stmp3xxx_setl(BM_APBH_CTRL0_CLKGATE, REGS_APBH_BASE + HW_APBH_CTRL0);
|
|
||||||
stmp3xxx_setl(BM_APBX_CTRL0_CLKGATE, REGS_APBX_BASE + HW_APBX_CTRL0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stmp3xxx_dma_resume(void)
|
|
||||||
{
|
|
||||||
stmp3xxx_clearl(BM_APBH_CTRL0_CLKGATE | BM_APBH_CTRL0_SFTRST,
|
|
||||||
REGS_APBH_BASE + HW_APBH_CTRL0);
|
|
||||||
stmp3xxx_clearl(BM_APBX_CTRL0_CLKGATE | BM_APBX_CTRL0_SFTRST,
|
|
||||||
REGS_APBX_BASE + HW_APBX_CTRL0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_FREQ
|
|
||||||
|
|
||||||
struct dma_notifier_block {
|
|
||||||
struct notifier_block nb;
|
|
||||||
void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int dma_cpufreq_notifier(struct notifier_block *self,
|
|
||||||
unsigned long phase, void *p)
|
|
||||||
{
|
|
||||||
switch (phase) {
|
|
||||||
case CPUFREQ_POSTCHANGE:
|
|
||||||
stmp3xxx_dma_resume();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CPUFREQ_PRECHANGE:
|
|
||||||
stmp3xxx_dma_suspend();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dma_notifier_block dma_cpufreq_nb = {
|
|
||||||
.nb = {
|
|
||||||
.notifier_call = dma_cpufreq_notifier,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
#endif /* CONFIG_CPU_FREQ */
|
|
||||||
|
|
||||||
void __init stmp3xxx_dma_init(void)
|
|
||||||
{
|
|
||||||
stmp3xxx_clearl(BM_APBH_CTRL0_CLKGATE | BM_APBH_CTRL0_SFTRST,
|
|
||||||
REGS_APBH_BASE + HW_APBH_CTRL0);
|
|
||||||
stmp3xxx_clearl(BM_APBX_CTRL0_CLKGATE | BM_APBX_CTRL0_SFTRST,
|
|
||||||
REGS_APBX_BASE + HW_APBX_CTRL0);
|
|
||||||
#ifdef CONFIG_CPU_FREQ
|
|
||||||
cpufreq_register_notifier(&dma_cpufreq_nb.nb,
|
|
||||||
CPUFREQ_TRANSITION_NOTIFIER);
|
|
||||||
#endif /* CONFIG_CPU_FREQ */
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_MACH_CLKDEV_H
|
|
||||||
#define __ASM_MACH_CLKDEV_H
|
|
||||||
|
|
||||||
#define __clk_get(clk) ({ 1; })
|
|
||||||
#define __clk_put(clk) do { } while (0)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* Freescale STMP37XX/STMP378X CPU type detection
|
|
||||||
*
|
|
||||||
* Embedded Alley Solutions, Inc <source@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_PLAT_CPU_H
|
|
||||||
#define __ASM_PLAT_CPU_H
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_STMP37XX
|
|
||||||
#define cpu_is_stmp37xx() (1)
|
|
||||||
#else
|
|
||||||
#define cpu_is_stmp37xx() (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_STMP378X
|
|
||||||
#define cpu_is_stmp378x() (1)
|
|
||||||
#else
|
|
||||||
#define cpu_is_stmp378x() (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_PLAT_CPU_H */
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* Debugging macro include header
|
|
||||||
*
|
|
||||||
* Embedded Alley Solutions, Inc <source@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
.macro addruart, rp, rv
|
|
||||||
mov \rp, #0x00070000
|
|
||||||
add \rv, \rp, #0xf0000000 @ virtual base
|
|
||||||
add \rp, \rp, #0x80000000 @ physical base
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro senduart,rd,rx
|
|
||||||
strb \rd, [\rx, #0] @ data register at 0
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro waituart,rd,rx
|
|
||||||
1001: ldr \rd, [\rx, #0x18] @ UARTFLG
|
|
||||||
tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full
|
|
||||||
bne 1001b
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro busyuart,rd,rx
|
|
||||||
1001: ldr \rd, [\rx, #0x18] @ UARTFLG
|
|
||||||
tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
|
|
||||||
bne 1001b
|
|
||||||
.endm
|
|
|
@ -1,153 +0,0 @@
|
||||||
/*
|
|
||||||
* Freescale STMP37XX/STMP378X DMA helper interface
|
|
||||||
*
|
|
||||||
* Embedded Alley Solutions, Inc <source@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_PLAT_STMP3XXX_DMA_H
|
|
||||||
#define __ASM_PLAT_STMP3XXX_DMA_H
|
|
||||||
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/dmapool.h>
|
|
||||||
|
|
||||||
#if !defined(MAX_PIO_WORDS)
|
|
||||||
#define MAX_PIO_WORDS (15)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define STMP3XXX_BUS_APBH 0
|
|
||||||
#define STMP3XXX_BUS_APBX 1
|
|
||||||
#define STMP3XXX_DMA_MAX_CHANNEL 16
|
|
||||||
#define STMP3XXX_DMA_BUS(dma) ((dma) / 16)
|
|
||||||
#define STMP3XXX_DMA_CHANNEL(dma) ((dma) % 16)
|
|
||||||
#define STMP3XXX_DMA(channel, bus) ((bus) * 16 + (channel))
|
|
||||||
#define MAX_DMA_ADDRESS 0xffffffff
|
|
||||||
#define MAX_DMA_CHANNELS 32
|
|
||||||
|
|
||||||
struct stmp3xxx_dma_command {
|
|
||||||
u32 next;
|
|
||||||
u32 cmd;
|
|
||||||
union {
|
|
||||||
u32 buf_ptr;
|
|
||||||
u32 alternate;
|
|
||||||
};
|
|
||||||
u32 pio_words[MAX_PIO_WORDS];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct stmp3xxx_dma_descriptor {
|
|
||||||
struct stmp3xxx_dma_command *command;
|
|
||||||
dma_addr_t handle;
|
|
||||||
|
|
||||||
/* The virtual address of the buffer pointer */
|
|
||||||
void *virtual_buf_ptr;
|
|
||||||
/* The next descriptor in a the DMA chain (optional) */
|
|
||||||
struct stmp3xxx_dma_descriptor *next_descr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct stmp37xx_circ_dma_chain {
|
|
||||||
unsigned total_count;
|
|
||||||
struct stmp3xxx_dma_descriptor *chain;
|
|
||||||
|
|
||||||
unsigned free_index;
|
|
||||||
unsigned free_count;
|
|
||||||
unsigned active_index;
|
|
||||||
unsigned active_count;
|
|
||||||
unsigned cooked_index;
|
|
||||||
unsigned cooked_count;
|
|
||||||
|
|
||||||
int bus;
|
|
||||||
unsigned channel;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct stmp3xxx_dma_descriptor
|
|
||||||
*stmp3xxx_dma_circ_get_free_head(struct stmp37xx_circ_dma_chain *chain)
|
|
||||||
{
|
|
||||||
return &(chain->chain[chain->free_index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct stmp3xxx_dma_descriptor
|
|
||||||
*stmp3xxx_dma_circ_get_cooked_head(struct stmp37xx_circ_dma_chain *chain)
|
|
||||||
{
|
|
||||||
return &(chain->chain[chain->cooked_index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int stmp3xxx_dma_request(int ch, struct device *dev, const char *name);
|
|
||||||
int stmp3xxx_dma_release(int ch);
|
|
||||||
int stmp3xxx_dma_allocate_command(int ch,
|
|
||||||
struct stmp3xxx_dma_descriptor *descriptor);
|
|
||||||
int stmp3xxx_dma_free_command(int ch,
|
|
||||||
struct stmp3xxx_dma_descriptor *descriptor);
|
|
||||||
void stmp3xxx_dma_continue(int channel, u32 semaphore);
|
|
||||||
void stmp3xxx_dma_go(int ch, struct stmp3xxx_dma_descriptor *head,
|
|
||||||
u32 semaphore);
|
|
||||||
int stmp3xxx_dma_running(int ch);
|
|
||||||
int stmp3xxx_dma_make_chain(int ch, struct stmp37xx_circ_dma_chain *chain,
|
|
||||||
struct stmp3xxx_dma_descriptor descriptors[],
|
|
||||||
unsigned items);
|
|
||||||
void stmp3xxx_dma_free_chain(struct stmp37xx_circ_dma_chain *chain);
|
|
||||||
void stmp37xx_circ_clear_chain(struct stmp37xx_circ_dma_chain *chain);
|
|
||||||
void stmp37xx_circ_advance_free(struct stmp37xx_circ_dma_chain *chain,
|
|
||||||
unsigned count);
|
|
||||||
void stmp37xx_circ_advance_active(struct stmp37xx_circ_dma_chain *chain,
|
|
||||||
unsigned count);
|
|
||||||
unsigned stmp37xx_circ_advance_cooked(struct stmp37xx_circ_dma_chain *chain);
|
|
||||||
int stmp3xxx_dma_read_semaphore(int ch);
|
|
||||||
void stmp3xxx_dma_init(void);
|
|
||||||
void stmp3xxx_dma_set_alt_target(int ch, int target);
|
|
||||||
void stmp3xxx_dma_suspend(void);
|
|
||||||
void stmp3xxx_dma_resume(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* STMP37xx and STMP378x have different DMA control
|
|
||||||
* registers layout
|
|
||||||
*/
|
|
||||||
|
|
||||||
void stmp3xxx_arch_dma_freeze(int ch);
|
|
||||||
void stmp3xxx_arch_dma_unfreeze(int ch);
|
|
||||||
void stmp3xxx_arch_dma_reset_channel(int ch);
|
|
||||||
void stmp3xxx_arch_dma_enable_interrupt(int ch);
|
|
||||||
void stmp3xxx_arch_dma_clear_interrupt(int ch);
|
|
||||||
int stmp3xxx_arch_dma_is_interrupt(int ch);
|
|
||||||
|
|
||||||
static inline void stmp3xxx_dma_reset_channel(int ch)
|
|
||||||
{
|
|
||||||
stmp3xxx_arch_dma_reset_channel(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void stmp3xxx_dma_freeze(int ch)
|
|
||||||
{
|
|
||||||
stmp3xxx_arch_dma_freeze(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stmp3xxx_dma_unfreeze(int ch)
|
|
||||||
{
|
|
||||||
stmp3xxx_arch_dma_unfreeze(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stmp3xxx_dma_enable_interrupt(int ch)
|
|
||||||
{
|
|
||||||
stmp3xxx_arch_dma_enable_interrupt(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stmp3xxx_dma_clear_interrupt(int ch)
|
|
||||||
{
|
|
||||||
stmp3xxx_arch_dma_clear_interrupt(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int stmp3xxx_dma_is_interrupt(int ch)
|
|
||||||
{
|
|
||||||
return stmp3xxx_arch_dma_is_interrupt(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __ASM_PLAT_STMP3XXX_DMA_H */
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Freescale STMP37XX/STMP378X GPIO interface
|
|
||||||
*
|
|
||||||
* Embedded Alley Solutions, Inc <source@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_PLAT_GPIO_H
|
|
||||||
#define __ASM_PLAT_GPIO_H
|
|
||||||
|
|
||||||
#define ARCH_NR_GPIOS (32 * 3)
|
|
||||||
#define gpio_to_irq(gpio) __gpio_to_irq(gpio)
|
|
||||||
#define gpio_get_value(gpio) __gpio_get_value(gpio)
|
|
||||||
#define gpio_set_value(gpio, value) __gpio_set_value(gpio, value)
|
|
||||||
|
|
||||||
#include <asm-generic/gpio.h>
|
|
||||||
|
|
||||||
#endif /* __ASM_PLAT_GPIO_H */
|
|
|
@ -1,12 +0,0 @@
|
||||||
#ifndef __MACH_GPMI_H
|
|
||||||
|
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <mach/regs-gpmi.h>
|
|
||||||
|
|
||||||
struct gpmi_platform_data {
|
|
||||||
void *pins;
|
|
||||||
int nr_parts;
|
|
||||||
struct mtd_partition *parts;
|
|
||||||
const char *part_types[];
|
|
||||||
};
|
|
||||||
#endif
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* This file contains the hardware definitions of the Freescale STMP3XXX
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 Sigmatel Inc
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_ARCH_HARDWARE_H
|
|
||||||
#define __ASM_ARCH_HARDWARE_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Where in virtual memory the IO devices (timers, system controllers
|
|
||||||
* and so on)
|
|
||||||
*/
|
|
||||||
#define IO_BASE 0xF0000000 /* VA of IO */
|
|
||||||
#define IO_SIZE 0x00100000 /* How much? */
|
|
||||||
#define IO_START 0x80000000 /* PA of IO */
|
|
||||||
|
|
||||||
/* macro to get at IO space when running virtually */
|
|
||||||
#define IO_ADDRESS(x) (((x) & 0x000fffff) | IO_BASE)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2005 Sigmatel Inc
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_ARM_ARCH_IO_H
|
|
||||||
#define __ASM_ARM_ARCH_IO_H
|
|
||||||
|
|
||||||
#define IO_SPACE_LIMIT 0xffffffff
|
|
||||||
|
|
||||||
#define __io(a) __typesafe_io(a)
|
|
||||||
#define __mem_pci(a) (a)
|
|
||||||
#define __mem_isa(a) (a)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,22 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_ARCH_MEMORY_H
|
|
||||||
#define __ASM_ARCH_MEMORY_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Physical DRAM offset.
|
|
||||||
*/
|
|
||||||
#define PLAT_PHYS_OFFSET UL(0x40000000)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,14 +0,0 @@
|
||||||
#ifndef _MACH_MMC_H
|
|
||||||
#define _MACH_MMC_H
|
|
||||||
|
|
||||||
#include <mach/regs-ssp.h>
|
|
||||||
|
|
||||||
struct stmp3xxxmmc_platform_data {
|
|
||||||
int (*get_wp)(void);
|
|
||||||
unsigned long (*setclock)(void __iomem *base, unsigned long);
|
|
||||||
void (*cmd_pullup)(int);
|
|
||||||
int (*hw_init)(void);
|
|
||||||
void (*hw_release)(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,157 +0,0 @@
|
||||||
/*
|
|
||||||
* Freescale STMP37XX/STMP378X Pin Multiplexing
|
|
||||||
*
|
|
||||||
* Author: Vladislav Buzov <vbuzov@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __PINMUX_H
|
|
||||||
#define __PINMUX_H
|
|
||||||
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/gpio.h>
|
|
||||||
#include <asm-generic/gpio.h>
|
|
||||||
|
|
||||||
/* Pin definitions */
|
|
||||||
#include "pins.h"
|
|
||||||
#include <mach/pins.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Each pin may be routed up to four different HW interfaces
|
|
||||||
* including GPIO
|
|
||||||
*/
|
|
||||||
enum pin_fun {
|
|
||||||
PIN_FUN1 = 0,
|
|
||||||
PIN_FUN2,
|
|
||||||
PIN_FUN3,
|
|
||||||
PIN_GPIO,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Each pin may have different output drive strength in range from
|
|
||||||
* 4mA to 20mA. The most common case is 4, 8 and 12 mA strengths.
|
|
||||||
*/
|
|
||||||
enum pin_strength {
|
|
||||||
PIN_4MA = 0,
|
|
||||||
PIN_8MA,
|
|
||||||
PIN_12MA,
|
|
||||||
PIN_16MA,
|
|
||||||
PIN_20MA,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Each pin can be programmed for 1.8V or 3.3V
|
|
||||||
*/
|
|
||||||
enum pin_voltage {
|
|
||||||
PIN_1_8V = 0,
|
|
||||||
PIN_3_3V,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Structure to define a group of pins and their parameters
|
|
||||||
*/
|
|
||||||
struct pin_desc {
|
|
||||||
unsigned id;
|
|
||||||
enum pin_fun fun;
|
|
||||||
enum pin_strength strength;
|
|
||||||
enum pin_voltage voltage;
|
|
||||||
unsigned pullup:1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pin_group {
|
|
||||||
struct pin_desc *pins;
|
|
||||||
int nr_pins;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Set pin drive strength */
|
|
||||||
void stmp3xxx_pin_strength(unsigned id, enum pin_strength strength,
|
|
||||||
const char *label);
|
|
||||||
|
|
||||||
/* Set pin voltage */
|
|
||||||
void stmp3xxx_pin_voltage(unsigned id, enum pin_voltage voltage,
|
|
||||||
const char *label);
|
|
||||||
|
|
||||||
/* Enable pull-up resistor for a pin */
|
|
||||||
void stmp3xxx_pin_pullup(unsigned id, int enable, const char *label);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Request a pin ownership, only one module (identified by @label)
|
|
||||||
* may own a pin.
|
|
||||||
*/
|
|
||||||
int stmp3xxx_request_pin(unsigned id, enum pin_fun fun, const char *label);
|
|
||||||
|
|
||||||
/* Release pin */
|
|
||||||
void stmp3xxx_release_pin(unsigned id, const char *label);
|
|
||||||
|
|
||||||
void stmp3xxx_set_pin_type(unsigned id, enum pin_fun fun);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Each bank is associated with a number of registers to control
|
|
||||||
* pin function, drive strength, voltage and pull-up reigster. The
|
|
||||||
* number of registers of a given type depends on the number of bits
|
|
||||||
* describin particular pin.
|
|
||||||
*/
|
|
||||||
#define HW_MUXSEL_NUM 2 /* registers per bank */
|
|
||||||
#define HW_MUXSEL_PIN_LEN 2 /* bits per pin */
|
|
||||||
#define HW_MUXSEL_PIN_NUM 16 /* pins per register */
|
|
||||||
#define HW_MUXSEL_PINFUN_MASK 0x3 /* pin function mask */
|
|
||||||
#define HW_MUXSEL_PINFUN_NUM 4 /* four options for a pin */
|
|
||||||
|
|
||||||
#define HW_DRIVE_NUM 4 /* registers per bank */
|
|
||||||
#define HW_DRIVE_PIN_LEN 4 /* bits per pin */
|
|
||||||
#define HW_DRIVE_PIN_NUM 8 /* pins per register */
|
|
||||||
#define HW_DRIVE_PINDRV_MASK 0x3 /* pin strength mask - 2 bits */
|
|
||||||
#define HW_DRIVE_PINDRV_NUM 5 /* five possible strength values */
|
|
||||||
#define HW_DRIVE_PINV_MASK 0x4 /* pin voltage mask - 1 bit */
|
|
||||||
|
|
||||||
|
|
||||||
struct stmp3xxx_pinmux_bank {
|
|
||||||
struct gpio_chip chip;
|
|
||||||
|
|
||||||
/* Pins allocation map */
|
|
||||||
unsigned long pin_map;
|
|
||||||
|
|
||||||
/* Pin owner names */
|
|
||||||
const char *pin_labels[32];
|
|
||||||
|
|
||||||
/* Bank registers */
|
|
||||||
void __iomem *hw_muxsel[HW_MUXSEL_NUM];
|
|
||||||
void __iomem *hw_drive[HW_DRIVE_NUM];
|
|
||||||
void __iomem *hw_pull;
|
|
||||||
|
|
||||||
void __iomem *pin2irq,
|
|
||||||
*irqlevel,
|
|
||||||
*irqpolarity,
|
|
||||||
*irqen,
|
|
||||||
*irqstat;
|
|
||||||
|
|
||||||
/* HW MUXSEL register function bit values */
|
|
||||||
u8 functions[HW_MUXSEL_PINFUN_NUM];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* HW DRIVE register strength bit values:
|
|
||||||
* 0xff - requested strength is not supported for this bank
|
|
||||||
*/
|
|
||||||
u8 strengths[HW_DRIVE_PINDRV_NUM];
|
|
||||||
|
|
||||||
/* GPIO things */
|
|
||||||
void __iomem *hw_gpio_in,
|
|
||||||
*hw_gpio_out,
|
|
||||||
*hw_gpio_doe;
|
|
||||||
int irq, virq;
|
|
||||||
};
|
|
||||||
|
|
||||||
int __init stmp3xxx_pinmux_init(int virtual_irq_start);
|
|
||||||
|
|
||||||
#endif /* __PINMUX_H */
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Freescale STMP37XX/STMP378X Pin multiplexing interface definitions
|
|
||||||
*
|
|
||||||
* Author: Vladislav Buzov <vbuzov@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_PLAT_PINS_H
|
|
||||||
#define __ASM_PLAT_PINS_H
|
|
||||||
|
|
||||||
#define STMP3XXX_PINID(bank, pin) (bank * 32 + pin)
|
|
||||||
#define STMP3XXX_PINID_TO_BANK(pinid) (pinid / 32)
|
|
||||||
#define STMP3XXX_PINID_TO_PINNUM(pinid) (pinid % 32)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Special invalid pin identificator to show a pin doesn't exist
|
|
||||||
*/
|
|
||||||
#define PINID_NO_PIN STMP3XXX_PINID(0xFF, 0xFF)
|
|
||||||
|
|
||||||
#endif /* __ASM_PLAT_PINS_H */
|
|
|
@ -1,68 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_PLAT_PLATFORM_H
|
|
||||||
#define __ASM_PLAT_PLATFORM_H
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
|
||||||
#include <linux/io.h>
|
|
||||||
#endif
|
|
||||||
#include <asm/sizes.h>
|
|
||||||
|
|
||||||
/* Virtual address where registers are mapped */
|
|
||||||
#define STMP3XXX_REGS_PHBASE 0x80000000
|
|
||||||
#ifdef __ASSEMBLER__
|
|
||||||
#define STMP3XXX_REGS_BASE 0xF0000000
|
|
||||||
#else
|
|
||||||
#define STMP3XXX_REGS_BASE (void __iomem *)0xF0000000
|
|
||||||
#endif
|
|
||||||
#define STMP3XXX_REGS_SIZE SZ_1M
|
|
||||||
|
|
||||||
/* Virtual address where OCRAM is mapped */
|
|
||||||
#define STMP3XXX_OCRAM_PHBASE 0x00000000
|
|
||||||
#ifdef __ASSEMBLER__
|
|
||||||
#define STMP3XXX_OCRAM_BASE 0xf1000000
|
|
||||||
#else
|
|
||||||
#define STMP3XXX_OCRAM_BASE (void __iomem *)0xf1000000
|
|
||||||
#endif
|
|
||||||
#define STMP3XXX_OCRAM_SIZE (32 * SZ_1K)
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_STMP37XX
|
|
||||||
#define IRQ_PRIORITY_REG_RD HW_ICOLL_PRIORITYn_RD
|
|
||||||
#define IRQ_PRIORITY_REG_WR HW_ICOLL_PRIORITYn_WR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_STMP378X
|
|
||||||
#define IRQ_PRIORITY_REG_RD HW_ICOLL_INTERRUPTn_RD
|
|
||||||
#define IRQ_PRIORITY_REG_WR HW_ICOLL_INTERRUPTn_WR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define HW_STMP3XXX_SET 0x04
|
|
||||||
#define HW_STMP3XXX_CLR 0x08
|
|
||||||
#define HW_STMP3XXX_TOG 0x0c
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
|
||||||
static inline void stmp3xxx_clearl(u32 v, void __iomem *r)
|
|
||||||
{
|
|
||||||
__raw_writel(v, r + HW_STMP3XXX_CLR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stmp3xxx_setl(u32 v, void __iomem *r)
|
|
||||||
{
|
|
||||||
__raw_writel(v, r + HW_STMP3XXX_SET);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BF(value, field) (((value) << BP_##field) & BM_##field)
|
|
||||||
|
|
||||||
#endif /* __ASM_ARCH_PLATFORM_H */
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* Freescale STMP37XX/STMP378X core structure and function declarations
|
|
||||||
*
|
|
||||||
* Embedded Alley Solutions, Inc <source@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_PLAT_STMP3XXX_H
|
|
||||||
#define __ASM_PLAT_STMP3XXX_H
|
|
||||||
|
|
||||||
#include <linux/irq.h>
|
|
||||||
|
|
||||||
extern struct sys_timer stmp3xxx_timer;
|
|
||||||
|
|
||||||
void stmp3xxx_init_irq(struct irq_chip *chip);
|
|
||||||
void stmp3xxx_init(void);
|
|
||||||
int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable);
|
|
||||||
extern struct platform_device stmp3xxx_dbguart,
|
|
||||||
stmp3xxx_appuart,
|
|
||||||
stmp3xxx_watchdog,
|
|
||||||
stmp3xxx_touchscreen,
|
|
||||||
stmp3xxx_keyboard,
|
|
||||||
stmp3xxx_gpmi,
|
|
||||||
stmp3xxx_mmc,
|
|
||||||
stmp3xxx_udc,
|
|
||||||
stmp3xxx_ehci,
|
|
||||||
stmp3xxx_rtc,
|
|
||||||
stmp3xxx_spi1,
|
|
||||||
stmp3xxx_spi2,
|
|
||||||
stmp3xxx_backlight,
|
|
||||||
stmp3xxx_rotdec,
|
|
||||||
stmp3xxx_dcp,
|
|
||||||
stmp3xxx_dcp_bootstream,
|
|
||||||
stmp3xxx_persistent,
|
|
||||||
stmp3xxx_framebuffer,
|
|
||||||
stmp3xxx_battery;
|
|
||||||
int stmp3xxx_ssp1_device_register(void);
|
|
||||||
int stmp3xxx_ssp2_device_register(void);
|
|
||||||
|
|
||||||
struct pin_group;
|
|
||||||
void stmp3xxx_release_pin_group(struct pin_group *pin_group, const char *label);
|
|
||||||
int stmp3xxx_request_pin_group(struct pin_group *pin_group, const char *label);
|
|
||||||
|
|
||||||
#endif /* __ASM_PLAT_STMP3XXX_H */
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2005 Sigmatel Inc
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_ARCH_SYSTEM_H
|
|
||||||
#define __ASM_ARCH_SYSTEM_H
|
|
||||||
|
|
||||||
#include <asm/proc-fns.h>
|
|
||||||
#include <mach/platform.h>
|
|
||||||
#include <mach/regs-clkctrl.h>
|
|
||||||
#include <mach/regs-power.h>
|
|
||||||
|
|
||||||
static inline void arch_idle(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* This should do all the clock switching
|
|
||||||
* and wait for interrupt tricks
|
|
||||||
*/
|
|
||||||
|
|
||||||
cpu_do_idle();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void arch_reset(char mode, const char *cmd)
|
|
||||||
{
|
|
||||||
/* Set BATTCHRG to default value */
|
|
||||||
__raw_writel(0x00010000, REGS_POWER_BASE + HW_POWER_CHARGE);
|
|
||||||
|
|
||||||
/* Set MINPWR to default value */
|
|
||||||
__raw_writel(0, REGS_POWER_BASE + HW_POWER_MINPWR);
|
|
||||||
|
|
||||||
/* Reset digital side of chip (but not power or RTC) */
|
|
||||||
__raw_writel(BM_CLKCTRL_RESET_DIG,
|
|
||||||
REGS_CLKCTRL_BASE + HW_CLKCTRL_RESET);
|
|
||||||
|
|
||||||
/* Should not return */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 1999 ARM Limited
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* System time clock is sourced from the 32k clock
|
|
||||||
*/
|
|
||||||
#define CLOCK_TICK_RATE (32768)
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_PLAT_UNCOMPRESS_H
|
|
||||||
#define __ASM_PLAT_UNCOMPRESS_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register includes are for when the MMU enabled; we need to define our
|
|
||||||
* own stuff here for pre-MMU use
|
|
||||||
*/
|
|
||||||
#define UARTDBG_BASE 0x80070000
|
|
||||||
#define UART(c) (((volatile unsigned *)UARTDBG_BASE)[c])
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This does not append a newline
|
|
||||||
*/
|
|
||||||
static void putc(char c)
|
|
||||||
{
|
|
||||||
/* Wait for TX fifo empty */
|
|
||||||
while ((UART(6) & (1<<7)) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Write byte */
|
|
||||||
UART(0) = c;
|
|
||||||
|
|
||||||
/* Wait for last bit to exit the UART */
|
|
||||||
while (UART(6) & (1<<3))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void flush(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* nothing to do
|
|
||||||
*/
|
|
||||||
#define arch_decomp_setup()
|
|
||||||
|
|
||||||
#define arch_decomp_wdog()
|
|
||||||
|
|
||||||
#endif /* __ASM_PLAT_UNCOMPRESS_H */
|
|
|
@ -1,12 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#define VMALLOC_END 0xf0000000UL
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
* Freescale STMP37XX/STMP378X common interrupt handling code
|
|
||||||
*
|
|
||||||
* Author: Vladislav Buzov <vbuzov@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/sysdev.h>
|
|
||||||
|
|
||||||
#include <mach/stmp3xxx.h>
|
|
||||||
#include <mach/platform.h>
|
|
||||||
#include <mach/regs-icoll.h>
|
|
||||||
|
|
||||||
void __init stmp3xxx_init_irq(struct irq_chip *chip)
|
|
||||||
{
|
|
||||||
unsigned int i, lv;
|
|
||||||
|
|
||||||
/* Reset the interrupt controller */
|
|
||||||
stmp3xxx_reset_block(REGS_ICOLL_BASE + HW_ICOLL_CTRL, true);
|
|
||||||
|
|
||||||
/* Disable all interrupts initially */
|
|
||||||
for (i = 0; i < NR_REAL_IRQS; i++) {
|
|
||||||
chip->irq_mask(irq_get_irq_data(i));
|
|
||||||
irq_set_chip_and_handler(i, chip, handle_level_irq);
|
|
||||||
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure vector is cleared */
|
|
||||||
for (lv = 0; lv < 4; lv++)
|
|
||||||
__raw_writel(1 << lv, REGS_ICOLL_BASE + HW_ICOLL_LEVELACK);
|
|
||||||
__raw_writel(0, REGS_ICOLL_BASE + HW_ICOLL_VECTOR);
|
|
||||||
|
|
||||||
/* Barrier */
|
|
||||||
(void)__raw_readl(REGS_ICOLL_BASE + HW_ICOLL_STAT);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,550 +0,0 @@
|
||||||
/*
|
|
||||||
* Freescale STMP378X/STMP378X Pin Multiplexing
|
|
||||||
*
|
|
||||||
* Author: Vladislav Buzov <vbuzov@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#define DEBUG
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/sysdev.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
|
||||||
#include <mach/platform.h>
|
|
||||||
#include <mach/regs-pinctrl.h>
|
|
||||||
#include <mach/pins.h>
|
|
||||||
#include <mach/pinmux.h>
|
|
||||||
|
|
||||||
#define NR_BANKS ARRAY_SIZE(pinmux_banks)
|
|
||||||
static struct stmp3xxx_pinmux_bank pinmux_banks[] = {
|
|
||||||
[0] = {
|
|
||||||
.hw_muxsel = {
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL0,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL1,
|
|
||||||
},
|
|
||||||
.hw_drive = {
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE0,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE1,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE2,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE3,
|
|
||||||
},
|
|
||||||
.hw_pull = REGS_PINCTRL_BASE + HW_PINCTRL_PULL0,
|
|
||||||
.functions = { 0x0, 0x1, 0x2, 0x3 },
|
|
||||||
.strengths = { 0x0, 0x1, 0x2, 0x3, 0xff },
|
|
||||||
|
|
||||||
.hw_gpio_in = REGS_PINCTRL_BASE + HW_PINCTRL_DIN0,
|
|
||||||
.hw_gpio_out = REGS_PINCTRL_BASE + HW_PINCTRL_DOUT0,
|
|
||||||
.hw_gpio_doe = REGS_PINCTRL_BASE + HW_PINCTRL_DOE0,
|
|
||||||
.irq = IRQ_GPIO0,
|
|
||||||
|
|
||||||
.pin2irq = REGS_PINCTRL_BASE + HW_PINCTRL_PIN2IRQ0,
|
|
||||||
.irqstat = REGS_PINCTRL_BASE + HW_PINCTRL_IRQSTAT0,
|
|
||||||
.irqlevel = REGS_PINCTRL_BASE + HW_PINCTRL_IRQLEVEL0,
|
|
||||||
.irqpolarity = REGS_PINCTRL_BASE + HW_PINCTRL_IRQPOL0,
|
|
||||||
.irqen = REGS_PINCTRL_BASE + HW_PINCTRL_IRQEN0,
|
|
||||||
},
|
|
||||||
[1] = {
|
|
||||||
.hw_muxsel = {
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL2,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL3,
|
|
||||||
},
|
|
||||||
.hw_drive = {
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE4,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE5,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE6,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE7,
|
|
||||||
},
|
|
||||||
.hw_pull = REGS_PINCTRL_BASE + HW_PINCTRL_PULL1,
|
|
||||||
.functions = { 0x0, 0x1, 0x2, 0x3 },
|
|
||||||
.strengths = { 0x0, 0x1, 0x2, 0x3, 0xff },
|
|
||||||
|
|
||||||
.hw_gpio_in = REGS_PINCTRL_BASE + HW_PINCTRL_DIN1,
|
|
||||||
.hw_gpio_out = REGS_PINCTRL_BASE + HW_PINCTRL_DOUT1,
|
|
||||||
.hw_gpio_doe = REGS_PINCTRL_BASE + HW_PINCTRL_DOE1,
|
|
||||||
.irq = IRQ_GPIO1,
|
|
||||||
|
|
||||||
.pin2irq = REGS_PINCTRL_BASE + HW_PINCTRL_PIN2IRQ1,
|
|
||||||
.irqstat = REGS_PINCTRL_BASE + HW_PINCTRL_IRQSTAT1,
|
|
||||||
.irqlevel = REGS_PINCTRL_BASE + HW_PINCTRL_IRQLEVEL1,
|
|
||||||
.irqpolarity = REGS_PINCTRL_BASE + HW_PINCTRL_IRQPOL1,
|
|
||||||
.irqen = REGS_PINCTRL_BASE + HW_PINCTRL_IRQEN1,
|
|
||||||
},
|
|
||||||
[2] = {
|
|
||||||
.hw_muxsel = {
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL4,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL5,
|
|
||||||
},
|
|
||||||
.hw_drive = {
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE8,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE9,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE10,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE11,
|
|
||||||
},
|
|
||||||
.hw_pull = REGS_PINCTRL_BASE + HW_PINCTRL_PULL2,
|
|
||||||
.functions = { 0x0, 0x1, 0x2, 0x3 },
|
|
||||||
.strengths = { 0x0, 0x1, 0x2, 0x1, 0x2 },
|
|
||||||
|
|
||||||
.hw_gpio_in = REGS_PINCTRL_BASE + HW_PINCTRL_DIN2,
|
|
||||||
.hw_gpio_out = REGS_PINCTRL_BASE + HW_PINCTRL_DOUT2,
|
|
||||||
.hw_gpio_doe = REGS_PINCTRL_BASE + HW_PINCTRL_DOE2,
|
|
||||||
.irq = IRQ_GPIO2,
|
|
||||||
|
|
||||||
.pin2irq = REGS_PINCTRL_BASE + HW_PINCTRL_PIN2IRQ2,
|
|
||||||
.irqstat = REGS_PINCTRL_BASE + HW_PINCTRL_IRQSTAT2,
|
|
||||||
.irqlevel = REGS_PINCTRL_BASE + HW_PINCTRL_IRQLEVEL2,
|
|
||||||
.irqpolarity = REGS_PINCTRL_BASE + HW_PINCTRL_IRQPOL2,
|
|
||||||
.irqen = REGS_PINCTRL_BASE + HW_PINCTRL_IRQEN2,
|
|
||||||
},
|
|
||||||
[3] = {
|
|
||||||
.hw_muxsel = {
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL6,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL7,
|
|
||||||
},
|
|
||||||
.hw_drive = {
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE12,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE13,
|
|
||||||
REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE14,
|
|
||||||
NULL,
|
|
||||||
},
|
|
||||||
.hw_pull = REGS_PINCTRL_BASE + HW_PINCTRL_PULL3,
|
|
||||||
.functions = {0x0, 0x1, 0x2, 0x3},
|
|
||||||
.strengths = {0x0, 0x1, 0x2, 0x3, 0xff},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct stmp3xxx_pinmux_bank *
|
|
||||||
stmp3xxx_pinmux_bank(unsigned id, unsigned *bank, unsigned *pin)
|
|
||||||
{
|
|
||||||
unsigned b, p;
|
|
||||||
|
|
||||||
b = STMP3XXX_PINID_TO_BANK(id);
|
|
||||||
p = STMP3XXX_PINID_TO_PINNUM(id);
|
|
||||||
BUG_ON(b >= NR_BANKS);
|
|
||||||
if (bank)
|
|
||||||
*bank = b;
|
|
||||||
if (pin)
|
|
||||||
*pin = p;
|
|
||||||
return &pinmux_banks[b];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if requested pin is owned by caller */
|
|
||||||
static int stmp3xxx_check_pin(unsigned id, const char *label)
|
|
||||||
{
|
|
||||||
unsigned pin;
|
|
||||||
struct stmp3xxx_pinmux_bank *pm = stmp3xxx_pinmux_bank(id, NULL, &pin);
|
|
||||||
|
|
||||||
if (!test_bit(pin, &pm->pin_map)) {
|
|
||||||
printk(KERN_WARNING
|
|
||||||
"%s: Accessing free pin %x, caller %s\n",
|
|
||||||
__func__, id, label);
|
|
||||||
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (label && pm->pin_labels[pin] &&
|
|
||||||
strcmp(label, pm->pin_labels[pin])) {
|
|
||||||
printk(KERN_WARNING
|
|
||||||
"%s: Wrong pin owner %x, caller %s owner %s\n",
|
|
||||||
__func__, id, label, pm->pin_labels[pin]);
|
|
||||||
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void stmp3xxx_pin_strength(unsigned id, enum pin_strength strength,
|
|
||||||
const char *label)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pbank;
|
|
||||||
void __iomem *hwdrive;
|
|
||||||
u32 shift, val;
|
|
||||||
u32 bank, pin;
|
|
||||||
|
|
||||||
pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
|
|
||||||
pr_debug("%s: label %s bank %d pin %d strength %d\n", __func__, label,
|
|
||||||
bank, pin, strength);
|
|
||||||
|
|
||||||
hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM];
|
|
||||||
shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN;
|
|
||||||
val = pbank->strengths[strength];
|
|
||||||
if (val == 0xff) {
|
|
||||||
printk(KERN_WARNING
|
|
||||||
"%s: strength is not supported for bank %d, caller %s",
|
|
||||||
__func__, bank, label);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stmp3xxx_check_pin(id, label))
|
|
||||||
return;
|
|
||||||
|
|
||||||
pr_debug("%s: writing 0x%x to 0x%p register\n", __func__,
|
|
||||||
val << shift, hwdrive);
|
|
||||||
stmp3xxx_clearl(HW_DRIVE_PINDRV_MASK << shift, hwdrive);
|
|
||||||
stmp3xxx_setl(val << shift, hwdrive);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stmp3xxx_pin_voltage(unsigned id, enum pin_voltage voltage,
|
|
||||||
const char *label)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pbank;
|
|
||||||
void __iomem *hwdrive;
|
|
||||||
u32 shift;
|
|
||||||
u32 bank, pin;
|
|
||||||
|
|
||||||
pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
|
|
||||||
pr_debug("%s: label %s bank %d pin %d voltage %d\n", __func__, label,
|
|
||||||
bank, pin, voltage);
|
|
||||||
|
|
||||||
hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM];
|
|
||||||
shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN;
|
|
||||||
|
|
||||||
if (stmp3xxx_check_pin(id, label))
|
|
||||||
return;
|
|
||||||
|
|
||||||
pr_debug("%s: changing 0x%x bit in 0x%p register\n",
|
|
||||||
__func__, HW_DRIVE_PINV_MASK << shift, hwdrive);
|
|
||||||
if (voltage == PIN_1_8V)
|
|
||||||
stmp3xxx_clearl(HW_DRIVE_PINV_MASK << shift, hwdrive);
|
|
||||||
else
|
|
||||||
stmp3xxx_setl(HW_DRIVE_PINV_MASK << shift, hwdrive);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stmp3xxx_pin_pullup(unsigned id, int enable, const char *label)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pbank;
|
|
||||||
void __iomem *hwpull;
|
|
||||||
u32 bank, pin;
|
|
||||||
|
|
||||||
pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
|
|
||||||
pr_debug("%s: label %s bank %d pin %d enable %d\n", __func__, label,
|
|
||||||
bank, pin, enable);
|
|
||||||
|
|
||||||
hwpull = pbank->hw_pull;
|
|
||||||
|
|
||||||
if (stmp3xxx_check_pin(id, label))
|
|
||||||
return;
|
|
||||||
|
|
||||||
pr_debug("%s: changing 0x%x bit in 0x%p register\n",
|
|
||||||
__func__, 1 << pin, hwpull);
|
|
||||||
if (enable)
|
|
||||||
stmp3xxx_setl(1 << pin, hwpull);
|
|
||||||
else
|
|
||||||
stmp3xxx_clearl(1 << pin, hwpull);
|
|
||||||
}
|
|
||||||
|
|
||||||
int stmp3xxx_request_pin(unsigned id, enum pin_fun fun, const char *label)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pbank;
|
|
||||||
u32 bank, pin;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
|
|
||||||
pr_debug("%s: label %s bank %d pin %d fun %d\n", __func__, label,
|
|
||||||
bank, pin, fun);
|
|
||||||
|
|
||||||
if (test_bit(pin, &pbank->pin_map)) {
|
|
||||||
printk(KERN_WARNING
|
|
||||||
"%s: CONFLICT DETECTED pin %d:%d caller %s owner %s\n",
|
|
||||||
__func__, bank, pin, label, pbank->pin_labels[pin]);
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_bit(pin, &pbank->pin_map);
|
|
||||||
pbank->pin_labels[pin] = label;
|
|
||||||
|
|
||||||
stmp3xxx_set_pin_type(id, fun);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void stmp3xxx_set_pin_type(unsigned id, enum pin_fun fun)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pbank;
|
|
||||||
void __iomem *hwmux;
|
|
||||||
u32 shift, val;
|
|
||||||
u32 bank, pin;
|
|
||||||
|
|
||||||
pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
|
|
||||||
|
|
||||||
hwmux = pbank->hw_muxsel[pin / HW_MUXSEL_PIN_NUM];
|
|
||||||
shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN;
|
|
||||||
|
|
||||||
val = pbank->functions[fun];
|
|
||||||
shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN;
|
|
||||||
pr_debug("%s: writing 0x%x to 0x%p register\n",
|
|
||||||
__func__, val << shift, hwmux);
|
|
||||||
stmp3xxx_clearl(HW_MUXSEL_PINFUN_MASK << shift, hwmux);
|
|
||||||
stmp3xxx_setl(val << shift, hwmux);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stmp3xxx_release_pin(unsigned id, const char *label)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pbank;
|
|
||||||
u32 bank, pin;
|
|
||||||
|
|
||||||
pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
|
|
||||||
pr_debug("%s: label %s bank %d pin %d\n", __func__, label, bank, pin);
|
|
||||||
|
|
||||||
if (stmp3xxx_check_pin(id, label))
|
|
||||||
return;
|
|
||||||
|
|
||||||
clear_bit(pin, &pbank->pin_map);
|
|
||||||
pbank->pin_labels[pin] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int stmp3xxx_request_pin_group(struct pin_group *pin_group, const char *label)
|
|
||||||
{
|
|
||||||
struct pin_desc *pin;
|
|
||||||
int p;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
/* Allocate and configure pins */
|
|
||||||
for (p = 0; p < pin_group->nr_pins; p++) {
|
|
||||||
pr_debug("%s: #%d\n", __func__, p);
|
|
||||||
pin = &pin_group->pins[p];
|
|
||||||
|
|
||||||
err = stmp3xxx_request_pin(pin->id, pin->fun, label);
|
|
||||||
if (err)
|
|
||||||
goto out_err;
|
|
||||||
|
|
||||||
stmp3xxx_pin_strength(pin->id, pin->strength, label);
|
|
||||||
stmp3xxx_pin_voltage(pin->id, pin->voltage, label);
|
|
||||||
stmp3xxx_pin_pullup(pin->id, pin->pullup, label);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out_err:
|
|
||||||
/* Release allocated pins in case of error */
|
|
||||||
while (--p >= 0) {
|
|
||||||
pr_debug("%s: releasing #%d\n", __func__, p);
|
|
||||||
stmp3xxx_release_pin(pin_group->pins[p].id, label);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_request_pin_group);
|
|
||||||
|
|
||||||
void stmp3xxx_release_pin_group(struct pin_group *pin_group, const char *label)
|
|
||||||
{
|
|
||||||
struct pin_desc *pin;
|
|
||||||
int p;
|
|
||||||
|
|
||||||
for (p = 0; p < pin_group->nr_pins; p++) {
|
|
||||||
pin = &pin_group->pins[p];
|
|
||||||
stmp3xxx_release_pin(pin->id, label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(stmp3xxx_release_pin_group);
|
|
||||||
|
|
||||||
static int stmp3xxx_irq_data_to_gpio(struct irq_data *d,
|
|
||||||
struct stmp3xxx_pinmux_bank **bank, unsigned *gpio)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pm;
|
|
||||||
|
|
||||||
for (pm = pinmux_banks; pm < pinmux_banks + NR_BANKS; pm++)
|
|
||||||
if (pm->virq <= d->irq && d->irq < pm->virq + 32) {
|
|
||||||
*bank = pm;
|
|
||||||
*gpio = d->irq - pm->virq;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stmp3xxx_set_irqtype(struct irq_data *d, unsigned type)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pm;
|
|
||||||
unsigned gpio;
|
|
||||||
int l, p;
|
|
||||||
|
|
||||||
stmp3xxx_irq_data_to_gpio(d, &pm, &gpio);
|
|
||||||
switch (type) {
|
|
||||||
case IRQ_TYPE_EDGE_RISING:
|
|
||||||
l = 0; p = 1; break;
|
|
||||||
case IRQ_TYPE_EDGE_FALLING:
|
|
||||||
l = 0; p = 0; break;
|
|
||||||
case IRQ_TYPE_LEVEL_HIGH:
|
|
||||||
l = 1; p = 1; break;
|
|
||||||
case IRQ_TYPE_LEVEL_LOW:
|
|
||||||
l = 1; p = 0; break;
|
|
||||||
default:
|
|
||||||
pr_debug("%s: Incorrect GPIO interrupt type 0x%x\n",
|
|
||||||
__func__, type);
|
|
||||||
return -ENXIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l)
|
|
||||||
stmp3xxx_setl(1 << gpio, pm->irqlevel);
|
|
||||||
else
|
|
||||||
stmp3xxx_clearl(1 << gpio, pm->irqlevel);
|
|
||||||
if (p)
|
|
||||||
stmp3xxx_setl(1 << gpio, pm->irqpolarity);
|
|
||||||
else
|
|
||||||
stmp3xxx_clearl(1 << gpio, pm->irqpolarity);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stmp3xxx_pin_ack_irq(struct irq_data *d)
|
|
||||||
{
|
|
||||||
u32 stat;
|
|
||||||
struct stmp3xxx_pinmux_bank *pm;
|
|
||||||
unsigned gpio;
|
|
||||||
|
|
||||||
stmp3xxx_irq_data_to_gpio(d, &pm, &gpio);
|
|
||||||
stat = __raw_readl(pm->irqstat) & (1 << gpio);
|
|
||||||
stmp3xxx_clearl(stat, pm->irqstat);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stmp3xxx_pin_mask_irq(struct irq_data *d)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pm;
|
|
||||||
unsigned gpio;
|
|
||||||
|
|
||||||
stmp3xxx_irq_data_to_gpio(d, &pm, &gpio);
|
|
||||||
stmp3xxx_clearl(1 << gpio, pm->irqen);
|
|
||||||
stmp3xxx_clearl(1 << gpio, pm->pin2irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stmp3xxx_pin_unmask_irq(struct irq_data *d)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pm;
|
|
||||||
unsigned gpio;
|
|
||||||
|
|
||||||
stmp3xxx_irq_data_to_gpio(d, &pm, &gpio);
|
|
||||||
stmp3xxx_setl(1 << gpio, pm->irqen);
|
|
||||||
stmp3xxx_setl(1 << gpio, pm->pin2irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
struct stmp3xxx_pinmux_bank *to_pinmux_bank(struct gpio_chip *chip)
|
|
||||||
{
|
|
||||||
return container_of(chip, struct stmp3xxx_pinmux_bank, chip);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stmp3xxx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
|
|
||||||
return pm->virq + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stmp3xxx_gpio_get(struct gpio_chip *chip, unsigned offset)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
|
|
||||||
unsigned v;
|
|
||||||
|
|
||||||
v = __raw_readl(pm->hw_gpio_in) & (1 << offset);
|
|
||||||
return v ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stmp3xxx_gpio_set(struct gpio_chip *chip, unsigned offset, int v)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
|
|
||||||
|
|
||||||
if (v)
|
|
||||||
stmp3xxx_setl(1 << offset, pm->hw_gpio_out);
|
|
||||||
else
|
|
||||||
stmp3xxx_clearl(1 << offset, pm->hw_gpio_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stmp3xxx_gpio_output(struct gpio_chip *chip, unsigned offset, int v)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
|
|
||||||
|
|
||||||
stmp3xxx_setl(1 << offset, pm->hw_gpio_doe);
|
|
||||||
stmp3xxx_gpio_set(chip, offset, v);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stmp3xxx_gpio_input(struct gpio_chip *chip, unsigned offset)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
|
|
||||||
|
|
||||||
stmp3xxx_clearl(1 << offset, pm->hw_gpio_doe);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stmp3xxx_gpio_request(struct gpio_chip *chip, unsigned offset)
|
|
||||||
{
|
|
||||||
return stmp3xxx_request_pin(chip->base + offset, PIN_GPIO, "gpio");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stmp3xxx_gpio_free(struct gpio_chip *chip, unsigned offset)
|
|
||||||
{
|
|
||||||
stmp3xxx_release_pin(chip->base + offset, "gpio");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stmp3xxx_gpio_irq(u32 irq, struct irq_desc *desc)
|
|
||||||
{
|
|
||||||
struct stmp3xxx_pinmux_bank *pm = irq_get_handler_data(irq);
|
|
||||||
int gpio_irq = pm->virq;
|
|
||||||
u32 stat = __raw_readl(pm->irqstat);
|
|
||||||
|
|
||||||
while (stat) {
|
|
||||||
if (stat & 1)
|
|
||||||
generic_handle_irq(gpio_irq);
|
|
||||||
gpio_irq++;
|
|
||||||
stat >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip gpio_irq_chip = {
|
|
||||||
.irq_ack = stmp3xxx_pin_ack_irq,
|
|
||||||
.irq_mask = stmp3xxx_pin_mask_irq,
|
|
||||||
.irq_unmask = stmp3xxx_pin_unmask_irq,
|
|
||||||
.irq_set_type = stmp3xxx_set_irqtype,
|
|
||||||
};
|
|
||||||
|
|
||||||
int __init stmp3xxx_pinmux_init(int virtual_irq_start)
|
|
||||||
{
|
|
||||||
int b, r = 0;
|
|
||||||
struct stmp3xxx_pinmux_bank *pm;
|
|
||||||
int virq;
|
|
||||||
|
|
||||||
for (b = 0; b < 3; b++) {
|
|
||||||
/* only banks 0,1,2 are allowed to GPIO */
|
|
||||||
pm = pinmux_banks + b;
|
|
||||||
pm->chip.base = 32 * b;
|
|
||||||
pm->chip.ngpio = 32;
|
|
||||||
pm->chip.owner = THIS_MODULE;
|
|
||||||
pm->chip.can_sleep = 1;
|
|
||||||
pm->chip.exported = 1;
|
|
||||||
pm->chip.to_irq = stmp3xxx_gpio_to_irq;
|
|
||||||
pm->chip.direction_input = stmp3xxx_gpio_input;
|
|
||||||
pm->chip.direction_output = stmp3xxx_gpio_output;
|
|
||||||
pm->chip.get = stmp3xxx_gpio_get;
|
|
||||||
pm->chip.set = stmp3xxx_gpio_set;
|
|
||||||
pm->chip.request = stmp3xxx_gpio_request;
|
|
||||||
pm->chip.free = stmp3xxx_gpio_free;
|
|
||||||
pm->virq = virtual_irq_start + b * 32;
|
|
||||||
|
|
||||||
for (virq = pm->virq; virq < pm->virq; virq++) {
|
|
||||||
gpio_irq_chip.irq_mask(irq_get_irq_data(virq));
|
|
||||||
irq_set_chip_and_handler(virq, &gpio_irq_chip,
|
|
||||||
handle_level_irq);
|
|
||||||
set_irq_flags(virq, IRQF_VALID);
|
|
||||||
}
|
|
||||||
r = gpiochip_add(&pm->chip);
|
|
||||||
if (r < 0)
|
|
||||||
break;
|
|
||||||
irq_set_chained_handler(pm->irq, stmp3xxx_gpio_irq);
|
|
||||||
irq_set_handler_data(pm->irq, pm);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Vladislav Buzov");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
|
@ -1,186 +0,0 @@
|
||||||
/*
|
|
||||||
* System timer for Freescale STMP37XX/STMP378X
|
|
||||||
*
|
|
||||||
* Embedded Alley Solutions, Inc <source@embeddedalley.com>
|
|
||||||
*
|
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code contained herein is licensed under the GNU General Public
|
|
||||||
* License. You may obtain a copy of the GNU General Public License
|
|
||||||
* Version 2 or later at the following locations:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/gpl-license.html
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*/
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/clocksource.h>
|
|
||||||
#include <linux/clockchips.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
|
|
||||||
#include <asm/mach/time.h>
|
|
||||||
#include <mach/stmp3xxx.h>
|
|
||||||
#include <mach/platform.h>
|
|
||||||
#include <mach/regs-timrot.h>
|
|
||||||
|
|
||||||
static irqreturn_t
|
|
||||||
stmp3xxx_timer_interrupt(int irq, void *dev_id)
|
|
||||||
{
|
|
||||||
struct clock_event_device *c = dev_id;
|
|
||||||
|
|
||||||
/* timer 0 */
|
|
||||||
if (__raw_readl(REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0) &
|
|
||||||
BM_TIMROT_TIMCTRLn_IRQ) {
|
|
||||||
stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
|
|
||||||
c->event_handler(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* timer 1 */
|
|
||||||
else if (__raw_readl(REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1)
|
|
||||||
& BM_TIMROT_TIMCTRLn_IRQ) {
|
|
||||||
stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
|
|
||||||
stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ_EN,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
|
|
||||||
__raw_writel(0xFFFF, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cycle_t stmp3xxx_clock_read(struct clocksource *cs)
|
|
||||||
{
|
|
||||||
return ~((__raw_readl(REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1)
|
|
||||||
& 0xFFFF0000) >> 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
stmp3xxx_timrot_set_next_event(unsigned long delta,
|
|
||||||
struct clock_event_device *dev)
|
|
||||||
{
|
|
||||||
/* reload the timer */
|
|
||||||
__raw_writel(delta, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
stmp3xxx_timrot_set_mode(enum clock_event_mode mode,
|
|
||||||
struct clock_event_device *dev)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct clock_event_device ckevt_timrot = {
|
|
||||||
.name = "timrot",
|
|
||||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
|
||||||
.shift = 32,
|
|
||||||
.set_next_event = stmp3xxx_timrot_set_next_event,
|
|
||||||
.set_mode = stmp3xxx_timrot_set_mode,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clocksource cksrc_stmp3xxx = {
|
|
||||||
.name = "cksrc_stmp3xxx",
|
|
||||||
.rating = 250,
|
|
||||||
.read = stmp3xxx_clock_read,
|
|
||||||
.mask = CLOCKSOURCE_MASK(16),
|
|
||||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct irqaction stmp3xxx_timer_irq = {
|
|
||||||
.name = "stmp3xxx_timer",
|
|
||||||
.flags = IRQF_DISABLED | IRQF_TIMER,
|
|
||||||
.handler = stmp3xxx_timer_interrupt,
|
|
||||||
.dev_id = &ckevt_timrot,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up timer interrupt, and return the current time in seconds.
|
|
||||||
*/
|
|
||||||
static void __init stmp3xxx_init_timer(void)
|
|
||||||
{
|
|
||||||
ckevt_timrot.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
|
|
||||||
ckevt_timrot.shift);
|
|
||||||
ckevt_timrot.min_delta_ns = clockevent_delta2ns(2, &ckevt_timrot);
|
|
||||||
ckevt_timrot.max_delta_ns = clockevent_delta2ns(0xFFF, &ckevt_timrot);
|
|
||||||
ckevt_timrot.cpumask = cpumask_of(0);
|
|
||||||
|
|
||||||
stmp3xxx_reset_block(REGS_TIMROT_BASE, false);
|
|
||||||
|
|
||||||
/* clear two timers */
|
|
||||||
__raw_writel(0, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
|
|
||||||
__raw_writel(0, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
|
|
||||||
|
|
||||||
/* configure them */
|
|
||||||
__raw_writel(
|
|
||||||
(8 << BP_TIMROT_TIMCTRLn_SELECT) | /* 32 kHz */
|
|
||||||
BM_TIMROT_TIMCTRLn_RELOAD |
|
|
||||||
BM_TIMROT_TIMCTRLn_UPDATE |
|
|
||||||
BM_TIMROT_TIMCTRLn_IRQ_EN,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
|
|
||||||
__raw_writel(
|
|
||||||
(8 << BP_TIMROT_TIMCTRLn_SELECT) | /* 32 kHz */
|
|
||||||
BM_TIMROT_TIMCTRLn_RELOAD |
|
|
||||||
BM_TIMROT_TIMCTRLn_UPDATE |
|
|
||||||
BM_TIMROT_TIMCTRLn_IRQ_EN,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
|
|
||||||
|
|
||||||
__raw_writel(CLOCK_TICK_RATE / HZ - 1,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
|
|
||||||
__raw_writel(0xFFFF, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
|
|
||||||
|
|
||||||
setup_irq(IRQ_TIMER0, &stmp3xxx_timer_irq);
|
|
||||||
|
|
||||||
clocksource_register_hz(&cksrc_stmp3xxx, CLOCK_TICK_RATE);
|
|
||||||
clockevents_register_device(&ckevt_timrot);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
|
||||||
|
|
||||||
void stmp3xxx_suspend_timer(void)
|
|
||||||
{
|
|
||||||
stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ_EN | BM_TIMROT_TIMCTRLn_IRQ,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
|
|
||||||
stmp3xxx_setl(BM_TIMROT_ROTCTRL_CLKGATE,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_ROTCTRL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stmp3xxx_resume_timer(void)
|
|
||||||
{
|
|
||||||
stmp3xxx_clearl(BM_TIMROT_ROTCTRL_SFTRST | BM_TIMROT_ROTCTRL_CLKGATE,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_ROTCTRL);
|
|
||||||
__raw_writel(
|
|
||||||
8 << BP_TIMROT_TIMCTRLn_SELECT | /* 32 kHz */
|
|
||||||
BM_TIMROT_TIMCTRLn_RELOAD |
|
|
||||||
BM_TIMROT_TIMCTRLn_UPDATE |
|
|
||||||
BM_TIMROT_TIMCTRLn_IRQ_EN,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
|
|
||||||
__raw_writel(
|
|
||||||
8 << BP_TIMROT_TIMCTRLn_SELECT | /* 32 kHz */
|
|
||||||
BM_TIMROT_TIMCTRLn_RELOAD |
|
|
||||||
BM_TIMROT_TIMCTRLn_UPDATE |
|
|
||||||
BM_TIMROT_TIMCTRLn_IRQ_EN,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
|
|
||||||
__raw_writel(CLOCK_TICK_RATE / HZ - 1,
|
|
||||||
REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
|
|
||||||
__raw_writel(0xFFFF, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define stmp3xxx_suspend_timer NULL
|
|
||||||
#define stmp3xxx_resume_timer NULL
|
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
|
||||||
|
|
||||||
struct sys_timer stmp3xxx_timer = {
|
|
||||||
.init = stmp3xxx_init_timer,
|
|
||||||
.suspend = stmp3xxx_suspend_timer,
|
|
||||||
.resume = stmp3xxx_resume_timer,
|
|
||||||
};
|
|
Loading…
Reference in New Issue