mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 06:34:11 +08:00
This is the pxa changes for v4.9 cycle.
This cycle is covering : - the removal of the legacy DMA API This is the major contributor to the negative diffstat, as dmaengine have taken over in this area. - IDE subsystem defconfig fixes - preparation for pxa25x to be device-tree compliant - various irq related fixes -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJX0ucrAAoJEAP2et0duMsSdsUP/j+HOYv8tqnJ4/Wl0byLPj7o IrEWe3Ul+ZGisiN6u5umRANVHUbgNCrPmTMNVa/u3UA2yfffrV1pn6oiJVsNWIt2 /f6Kbd+czy+r745DEx/zcHYqOp43KOPslzzYxJpRNVcuiEOQ2ljSdSZgmgwy9blv 9/l7BIlAQn/XgXwOPj7C8j/mOkYmxXh2BdHz7pVhIAqofj0CrqXYhvgOPxvEOOqk jD8dWDlvFb0yTvP2RcxhUbUo6aOYf9OpBuNOctKqwKzxFpTloP/D/hQ5doBabalM GBzw4835+69qnMtrF/9JPKj9+cR/qHEhGLgHaKRAIKcaMMP0ksiDOYWpfjpq2BOj q/uSoIKPN5I5s2i78o97jDWWofF5iO3tioeLqavn8O91ptWb4EFCRdBvmX3PLvAb fy0dbF5qKJgowgYaO+Oe54ZKWWZ9wJ1GFxV4y+dXWy8def4KdNXu2AV7YqwS8JeA ifmxrQrqPj8j21X7bVYwvD4mplSPkmviO1c734BL1zAd3V8PdP27V5gNR5DYWAyP Bppv6HM9JGGHLjXTXaw+MIJJis1Pqe6Ou4XAt1K9vbj5cFNMt4NJx9B5eJRmqPkj Bt6FPLYPpUgwGIK4CZ6vJ+s4G9eAnV/OiPNrrmtm0stiRRMcPBWFFaPZSKj0+1wc 2TbuaO393CcyoCyC5bKY =kAKB -----END PGP SIGNATURE----- Merge tag 'pxa-for-4.9' of https://github.com/rjarzmik/linux into next/soc Pull "This is the pxa changes for v4.9 cycle" from Robert Jarzmik: This cycle is covering : - the removal of the legacy DMA API This is the major contributor to the negative diffstat, as dmaengine have taken over in this area. - IDE subsystem defconfig fixes - preparation for pxa25x to be device-tree compliant - various irq related fixes * tag 'pxa-for-4.9' of https://github.com/rjarzmik/linux: ARM: pxa: pxa_cplds: fix interrupt handling ARM: pxa: remove irq init from dt machines ARM: pxa: Use kmalloc_array() in pxa_pm_init() ARM: pxa: magician: Remove duplicated I2C pins declaration ARM: pxa: fix GPIO double shifts arm: trizeps4_defconfig: disable IDE subsystem arm: pxa255-idp_defconfig: disable IDE subsystem arm: lpda270_defconfig: disable IDE subsystem arm: colibri_pxa270_defconfig: disable IDE subsystem ARM: pxa: add pxa25x device-tree support ARM: pxa: prepare pxa25x interrupts for device-tree platforms ARM: pxa: remove platform dma code ARM: pxa: remove devicetree boards from pxa_defconfig
This commit is contained in:
commit
be46f95b54
@ -83,7 +83,6 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
|
||||
CONFIG_BLK_DEV_NBD=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=8
|
||||
CONFIG_IDE=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_NET_ETHERNET=y
|
||||
|
@ -31,7 +31,6 @@ CONFIG_MTD_CFI_GEOMETRY=y
|
||||
# CONFIG_MTD_CFI_I1 is not set
|
||||
CONFIG_MTD_CFI_INTELEXT=y
|
||||
CONFIG_BLK_DEV_NBD=y
|
||||
CONFIG_IDE=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_NET_ETHERNET=y
|
||||
CONFIG_SMC91X=y
|
||||
|
@ -28,7 +28,6 @@ CONFIG_MTD_CFI_GEOMETRY=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
|
||||
# CONFIG_MTD_CFI_I1 is not set
|
||||
CONFIG_MTD_CFI_INTELEXT=y
|
||||
CONFIG_IDE=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_NET_ETHERNET=y
|
||||
CONFIG_SMC91X=y
|
||||
|
@ -26,8 +26,6 @@ CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_LDM_PARTITION=y
|
||||
CONFIG_CMDLINE_PARTITION=y
|
||||
CONFIG_ARCH_PXA=y
|
||||
CONFIG_MACH_PXA27X_DT=y
|
||||
CONFIG_MACH_PXA3XX_DT=y
|
||||
CONFIG_ARCH_LUBBOCK=y
|
||||
CONFIG_MACH_MAINSTONE=y
|
||||
CONFIG_MACH_ZYLONITE300=y
|
||||
|
@ -94,8 +94,6 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
|
||||
CONFIG_BLK_DEV_NBD=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=8
|
||||
CONFIG_IDE=y
|
||||
CONFIG_BLK_DEV_IDECS=m
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
|
@ -4,6 +4,17 @@ menu "Intel PXA2xx/PXA3xx Implementations"
|
||||
|
||||
comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
|
||||
|
||||
config MACH_PXA25X_DT
|
||||
bool "Support PXA25x platforms from device tree"
|
||||
select PINCTRL
|
||||
select POWER_SUPPLY
|
||||
select PXA25x
|
||||
select USE_OF
|
||||
help
|
||||
Include support for Marvell PXA25x based platforms using
|
||||
the device tree. Needn't select any other machine while
|
||||
MACH_PXA25x_DT is enabled.
|
||||
|
||||
config MACH_PXA27X_DT
|
||||
bool "Support PXA27x platforms from device tree"
|
||||
select PINCTRL
|
||||
|
@ -19,8 +19,9 @@ obj-$(CONFIG_CPU_PXA930) += pxa930.o
|
||||
# NOTE: keep the order of boards in accordance to their order in Kconfig
|
||||
|
||||
# Device Tree support
|
||||
obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o
|
||||
obj-$(CONFIG_MACH_PXA25X_DT) += pxa-dt.o
|
||||
obj-$(CONFIG_MACH_PXA27X_DT) += pxa-dt.o
|
||||
obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o
|
||||
|
||||
# Intel/Marvell Dev Platforms
|
||||
obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
|
||||
|
@ -131,16 +131,11 @@ static int corgi_should_wakeup(unsigned int resume_on_alarm)
|
||||
return is_resume;
|
||||
}
|
||||
|
||||
static unsigned long corgi_charger_wakeup(void)
|
||||
static bool corgi_charger_wakeup(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
ret = (!gpio_get_value(CORGI_GPIO_AC_IN) << GPIO_bit(CORGI_GPIO_AC_IN))
|
||||
| (!gpio_get_value(CORGI_GPIO_KEY_INT)
|
||||
<< GPIO_bit(CORGI_GPIO_KEY_INT))
|
||||
| (!gpio_get_value(CORGI_GPIO_WAKEUP)
|
||||
<< GPIO_bit(CORGI_GPIO_WAKEUP));
|
||||
return ret;
|
||||
return !gpio_get_value(CORGI_GPIO_AC_IN) ||
|
||||
!gpio_get_value(CORGI_GPIO_KEY_INT) ||
|
||||
!gpio_get_value(CORGI_GPIO_WAKEUP);
|
||||
}
|
||||
|
||||
unsigned long corgipm_read_devdata(int type)
|
||||
|
@ -54,3 +54,4 @@ extern struct platform_device pxa3xx_device_gpio;
|
||||
extern struct platform_device pxa93x_device_gpio;
|
||||
|
||||
void __init pxa_register_device(struct platform_device *dev, void *data);
|
||||
void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors);
|
||||
|
@ -33,14 +33,12 @@ extern void __init pxa26x_init_irq(void);
|
||||
|
||||
#define pxa27x_handle_irq ichp_handle_irq
|
||||
extern int __init pxa27x_clocks_init(void);
|
||||
extern void __init pxa27x_dt_init_irq(void);
|
||||
extern unsigned pxa27x_get_clk_frequency_khz(int);
|
||||
extern void __init pxa27x_init_irq(void);
|
||||
extern void __init pxa27x_map_io(void);
|
||||
|
||||
#define pxa3xx_handle_irq ichp_handle_irq
|
||||
extern int __init pxa3xx_clocks_init(void);
|
||||
extern void __init pxa3xx_dt_init_irq(void);
|
||||
extern void __init pxa3xx_init_irq(void);
|
||||
extern void __init pxa3xx_map_io(void);
|
||||
|
||||
|
@ -17,5 +17,4 @@
|
||||
/* DMA Controller Registers Definitions */
|
||||
#define DMAC_REGS_VIRT io_p2v(0x40000000)
|
||||
|
||||
#include <plat/dma.h>
|
||||
#endif /* _ASM_ARCH_DMA_H */
|
||||
|
@ -121,10 +121,6 @@ static unsigned long magician_pin_config[] __initdata = {
|
||||
GPIO107_GPIO, /* DS1WM_IRQ */
|
||||
GPIO108_GPIO, /* GSM_READY */
|
||||
GPIO115_GPIO, /* nPEN_IRQ */
|
||||
|
||||
/* I2C */
|
||||
GPIO117_I2C_SCL,
|
||||
GPIO118_I2C_SDA,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -104,7 +104,8 @@ static int __init pxa_pm_init(void)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sleep_save = kmalloc(pxa_cpu_pm_fns->save_count * sizeof(unsigned long),
|
||||
sleep_save = kmalloc_array(pxa_cpu_pm_fns->save_count,
|
||||
sizeof(*sleep_save),
|
||||
GFP_KERNEL);
|
||||
if (!sleep_save) {
|
||||
printk(KERN_ERR "failed to alloc memory for pm save\n");
|
||||
|
@ -18,6 +18,32 @@
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
#ifdef CONFIG_PXA25x
|
||||
static const char * const pxa25x_dt_board_compat[] __initconst = {
|
||||
"marvell,pxa250",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(PXA25X_DT, "Marvell PXA25x (Device Tree Support)")
|
||||
.map_io = pxa25x_map_io,
|
||||
.restart = pxa_restart,
|
||||
.dt_compat = pxa25x_dt_board_compat,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PXA27x
|
||||
static const char * const pxa27x_dt_board_compat[] __initconst = {
|
||||
"marvell,pxa270",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(PXA27X_DT, "Marvell PXA27x (Device Tree Support)")
|
||||
.map_io = pxa27x_map_io,
|
||||
.restart = pxa_restart,
|
||||
.dt_compat = pxa27x_dt_board_compat,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PXA3xx
|
||||
static const char *const pxa3xx_dt_board_compat[] __initconst = {
|
||||
"marvell,pxa300",
|
||||
@ -28,24 +54,7 @@ static const char *const pxa3xx_dt_board_compat[] __initconst = {
|
||||
|
||||
DT_MACHINE_START(PXA_DT, "Marvell PXA3xx (Device Tree Support)")
|
||||
.map_io = pxa3xx_map_io,
|
||||
.init_irq = pxa3xx_dt_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.restart = pxa_restart,
|
||||
.dt_compat = pxa3xx_dt_board_compat,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PXA27x
|
||||
static const char * const pxa27x_dt_board_compat[] __initconst = {
|
||||
"marvell,pxa270",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(PXA27X_DT, "Marvell PXA2xx (Device Tree Support)")
|
||||
.map_io = pxa27x_map_io,
|
||||
.init_irq = pxa27x_dt_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.restart = pxa_restart,
|
||||
.dt_compat = pxa27x_dt_board_compat,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqchip.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/suspend.h>
|
||||
@ -151,6 +152,16 @@ void __init pxa26x_init_irq(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init __init
|
||||
pxa25x_dt_init_irq(struct device_node *node, struct device_node *parent)
|
||||
{
|
||||
pxa_dt_irq_init(pxa25x_set_wake);
|
||||
set_handle_irq(ichp_handle_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
IRQCHIP_DECLARE(pxa25x_intc, "marvell,pxa-intc", pxa25x_dt_init_irq);
|
||||
|
||||
static struct map_desc pxa25x_io_desc[] __initdata = {
|
||||
{ /* Mem Ctl */
|
||||
.virtual = (unsigned long)SMEMC_VIRT,
|
||||
@ -198,20 +209,17 @@ static int __init pxa25x_init(void)
|
||||
|
||||
reset_status = RCSR;
|
||||
|
||||
if ((ret = pxa_init_dma(IRQ_DMA, 16)))
|
||||
return ret;
|
||||
|
||||
pxa25x_init_pm();
|
||||
|
||||
register_syscore_ops(&pxa_irq_syscore_ops);
|
||||
register_syscore_ops(&pxa2xx_mfp_syscore_ops);
|
||||
|
||||
if (!of_have_populated_dt()) {
|
||||
pxa2xx_set_dmac_info(16, 40);
|
||||
pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info);
|
||||
ret = platform_add_devices(pxa25x_devices,
|
||||
ARRAY_SIZE(pxa25x_devices));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
@ -233,11 +234,15 @@ void __init pxa27x_init_irq(void)
|
||||
pxa_init_irq(34, pxa27x_set_wake);
|
||||
}
|
||||
|
||||
void __init pxa27x_dt_init_irq(void)
|
||||
static int __init
|
||||
pxa27x_dt_init_irq(struct device_node *node, struct device_node *parent)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_OF))
|
||||
pxa_dt_irq_init(pxa27x_set_wake);
|
||||
set_handle_irq(ichp_handle_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
IRQCHIP_DECLARE(pxa27x_intc, "marvell,pxa-intc", pxa27x_dt_init_irq);
|
||||
|
||||
static struct map_desc pxa27x_io_desc[] __initdata = {
|
||||
{ /* Mem Ctl */
|
||||
@ -300,9 +305,6 @@ static int __init pxa27x_init(void)
|
||||
|
||||
reset_status = RCSR;
|
||||
|
||||
if ((ret = pxa_init_dma(IRQ_DMA, 32)))
|
||||
return ret;
|
||||
|
||||
pxa27x_init_pm();
|
||||
|
||||
register_syscore_ops(&pxa_irq_syscore_ops);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/pm.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
@ -356,11 +357,16 @@ void __init pxa3xx_init_irq(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
void __init pxa3xx_dt_init_irq(void)
|
||||
static int __init __init
|
||||
pxa3xx_dt_init_irq(struct device_node *node, struct device_node *parent)
|
||||
{
|
||||
__pxa3xx_init_irq();
|
||||
pxa_dt_irq_init(pxa3xx_set_wake);
|
||||
set_handle_irq(ichp_handle_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
IRQCHIP_DECLARE(pxa3xx_intc, "marvell,pxa-intc", pxa3xx_dt_init_irq);
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static struct map_desc pxa3xx_io_desc[] __initdata = {
|
||||
@ -438,9 +444,6 @@ static int __init pxa3xx_init(void)
|
||||
*/
|
||||
NDCR = (NDCR & ~NDCR_ND_ARB_EN) | NDCR_ND_ARB_CNTL;
|
||||
|
||||
if ((ret = pxa_init_dma(IRQ_DMA, 32)))
|
||||
return ret;
|
||||
|
||||
pxa3xx_init_pm();
|
||||
|
||||
register_syscore_ops(&pxa_irq_syscore_ops);
|
||||
|
@ -41,30 +41,35 @@ static irqreturn_t cplds_irq_handler(int in_irq, void *d)
|
||||
unsigned long pending;
|
||||
unsigned int bit;
|
||||
|
||||
do {
|
||||
pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
|
||||
for_each_set_bit(bit, &pending, CPLDS_NB_IRQ)
|
||||
generic_handle_irq(irq_find_mapping(fpga->irqdomain, bit));
|
||||
for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) {
|
||||
generic_handle_irq(irq_find_mapping(fpga->irqdomain,
|
||||
bit));
|
||||
}
|
||||
} while (pending);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void cplds_irq_mask_ack(struct irq_data *d)
|
||||
static void cplds_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct cplds *fpga = irq_data_get_irq_chip_data(d);
|
||||
unsigned int cplds_irq = irqd_to_hwirq(d);
|
||||
unsigned int set, bit = BIT(cplds_irq);
|
||||
unsigned int bit = BIT(cplds_irq);
|
||||
|
||||
fpga->irq_mask &= ~bit;
|
||||
writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
|
||||
set = readl(fpga->base + FPGA_IRQ_SET_CLR);
|
||||
writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR);
|
||||
}
|
||||
|
||||
static void cplds_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct cplds *fpga = irq_data_get_irq_chip_data(d);
|
||||
unsigned int cplds_irq = irqd_to_hwirq(d);
|
||||
unsigned int bit = BIT(cplds_irq);
|
||||
unsigned int set, bit = BIT(cplds_irq);
|
||||
|
||||
set = readl(fpga->base + FPGA_IRQ_SET_CLR);
|
||||
writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR);
|
||||
|
||||
fpga->irq_mask |= bit;
|
||||
writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
|
||||
@ -72,7 +77,8 @@ static void cplds_irq_unmask(struct irq_data *d)
|
||||
|
||||
static struct irq_chip cplds_irq_chip = {
|
||||
.name = "pxa_cplds",
|
||||
.irq_mask_ack = cplds_irq_mask_ack,
|
||||
.irq_ack = cplds_irq_mask,
|
||||
.irq_mask = cplds_irq_mask,
|
||||
.irq_unmask = cplds_irq_unmask,
|
||||
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
@ -744,7 +744,7 @@ static int sharpsl_off_charge_battery(void)
|
||||
time = RCNR;
|
||||
while (1) {
|
||||
/* Check if any wakeup event had occurred */
|
||||
if (sharpsl_pm.machinfo->charger_wakeup() != 0)
|
||||
if (sharpsl_pm.machinfo->charger_wakeup())
|
||||
return 0;
|
||||
/* Check for timeout */
|
||||
if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
|
||||
|
@ -34,7 +34,7 @@ struct sharpsl_charger_machinfo {
|
||||
#define SHARPSL_STATUS_LOCK 5
|
||||
#define SHARPSL_STATUS_CHRGFULL 6
|
||||
#define SHARPSL_STATUS_FATAL 7
|
||||
unsigned long (*charger_wakeup)(void);
|
||||
bool (*charger_wakeup)(void);
|
||||
int (*should_wakeup)(unsigned int resume_on_alarm);
|
||||
void (*backlight_limit)(int);
|
||||
int (*backlight_get_status) (void);
|
||||
|
@ -165,13 +165,10 @@ static int spitz_should_wakeup(unsigned int resume_on_alarm)
|
||||
return is_resume;
|
||||
}
|
||||
|
||||
static unsigned long spitz_charger_wakeup(void)
|
||||
static bool spitz_charger_wakeup(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
ret = ((!gpio_get_value(SPITZ_GPIO_KEY_INT)
|
||||
<< GPIO_bit(SPITZ_GPIO_KEY_INT))
|
||||
| gpio_get_value(SPITZ_GPIO_SYNC));
|
||||
return ret;
|
||||
return !gpio_get_value(SPITZ_GPIO_KEY_INT) ||
|
||||
gpio_get_value(SPITZ_GPIO_SYNC);
|
||||
}
|
||||
|
||||
unsigned long spitzpm_read_devdata(int type)
|
||||
|
@ -3,8 +3,6 @@
|
||||
#
|
||||
ccflags-$(CONFIG_ARCH_MMP) := -I$(srctree)/$(src)/include
|
||||
|
||||
obj-$(CONFIG_ARCH_PXA) := dma.o
|
||||
|
||||
obj-$(CONFIG_PXA3xx) += mfp.o
|
||||
obj-$(CONFIG_ARCH_MMP) += mfp.o
|
||||
|
||||
|
@ -1,386 +0,0 @@
|
||||
/*
|
||||
* linux/arch/arm/plat-pxa/dma.c
|
||||
*
|
||||
* PXA DMA registration and IRQ dispatching
|
||||
*
|
||||
* Author: Nicolas Pitre
|
||||
* Created: Nov 15, 2001
|
||||
* Copyright: MontaVista Software Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/memory.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/dma.h>
|
||||
|
||||
#define DMA_DEBUG_NAME "pxa_dma"
|
||||
#define DMA_MAX_REQUESTERS 64
|
||||
|
||||
struct dma_channel {
|
||||
char *name;
|
||||
pxa_dma_prio prio;
|
||||
void (*irq_handler)(int, void *);
|
||||
void *data;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static struct dma_channel *dma_channels;
|
||||
static int num_dma_channels;
|
||||
|
||||
/*
|
||||
* Debug fs
|
||||
*/
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
static struct dentry *dbgfs_root, *dbgfs_state, **dbgfs_chan;
|
||||
|
||||
static int dbg_show_requester_chan(struct seq_file *s, void *p)
|
||||
{
|
||||
int chan = (int)s->private;
|
||||
int i;
|
||||
u32 drcmr;
|
||||
|
||||
seq_printf(s, "DMA channel %d requesters list :\n", chan);
|
||||
for (i = 0; i < DMA_MAX_REQUESTERS; i++) {
|
||||
drcmr = DRCMR(i);
|
||||
if ((drcmr & DRCMR_CHLNUM) == chan)
|
||||
seq_printf(s, "\tRequester %d (MAPVLD=%d)\n",
|
||||
i, !!(drcmr & DRCMR_MAPVLD));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int dbg_burst_from_dcmd(u32 dcmd)
|
||||
{
|
||||
int burst = (dcmd >> 16) & 0x3;
|
||||
|
||||
return burst ? 4 << burst : 0;
|
||||
}
|
||||
|
||||
static int is_phys_valid(unsigned long addr)
|
||||
{
|
||||
return pfn_valid(__phys_to_pfn(addr));
|
||||
}
|
||||
|
||||
#define DCSR_STR(flag) (dcsr & DCSR_##flag ? #flag" " : "")
|
||||
#define DCMD_STR(flag) (dcmd & DCMD_##flag ? #flag" " : "")
|
||||
|
||||
static int dbg_show_descriptors(struct seq_file *s, void *p)
|
||||
{
|
||||
int chan = (int)s->private;
|
||||
int i, max_show = 20, burst, width;
|
||||
u32 dcmd;
|
||||
unsigned long phys_desc;
|
||||
struct pxa_dma_desc *desc;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dma_channels[chan].lock, flags);
|
||||
phys_desc = DDADR(chan);
|
||||
|
||||
seq_printf(s, "DMA channel %d descriptors :\n", chan);
|
||||
seq_printf(s, "[%03d] First descriptor unknown\n", 0);
|
||||
for (i = 1; i < max_show && is_phys_valid(phys_desc); i++) {
|
||||
desc = phys_to_virt(phys_desc);
|
||||
dcmd = desc->dcmd;
|
||||
burst = dbg_burst_from_dcmd(dcmd);
|
||||
width = (1 << ((dcmd >> 14) & 0x3)) >> 1;
|
||||
|
||||
seq_printf(s, "[%03d] Desc at %08lx(virt %p)\n",
|
||||
i, phys_desc, desc);
|
||||
seq_printf(s, "\tDDADR = %08x\n", desc->ddadr);
|
||||
seq_printf(s, "\tDSADR = %08x\n", desc->dsadr);
|
||||
seq_printf(s, "\tDTADR = %08x\n", desc->dtadr);
|
||||
seq_printf(s, "\tDCMD = %08x (%s%s%s%s%s%s%sburst=%d width=%d len=%d)\n",
|
||||
dcmd,
|
||||
DCMD_STR(INCSRCADDR), DCMD_STR(INCTRGADDR),
|
||||
DCMD_STR(FLOWSRC), DCMD_STR(FLOWTRG),
|
||||
DCMD_STR(STARTIRQEN), DCMD_STR(ENDIRQEN),
|
||||
DCMD_STR(ENDIAN), burst, width,
|
||||
dcmd & DCMD_LENGTH);
|
||||
phys_desc = desc->ddadr;
|
||||
}
|
||||
if (i == max_show)
|
||||
seq_printf(s, "[%03d] Desc at %08lx ... max display reached\n",
|
||||
i, phys_desc);
|
||||
else
|
||||
seq_printf(s, "[%03d] Desc at %08lx is %s\n",
|
||||
i, phys_desc, phys_desc == DDADR_STOP ?
|
||||
"DDADR_STOP" : "invalid");
|
||||
|
||||
spin_unlock_irqrestore(&dma_channels[chan].lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dbg_show_chan_state(struct seq_file *s, void *p)
|
||||
{
|
||||
int chan = (int)s->private;
|
||||
u32 dcsr, dcmd;
|
||||
int burst, width;
|
||||
static char *str_prio[] = { "high", "normal", "low" };
|
||||
|
||||
dcsr = DCSR(chan);
|
||||
dcmd = DCMD(chan);
|
||||
burst = dbg_burst_from_dcmd(dcmd);
|
||||
width = (1 << ((dcmd >> 14) & 0x3)) >> 1;
|
||||
|
||||
seq_printf(s, "DMA channel %d\n", chan);
|
||||
seq_printf(s, "\tPriority : %s\n", str_prio[dma_channels[chan].prio]);
|
||||
seq_printf(s, "\tUnaligned transfer bit: %s\n",
|
||||
DALGN & (1 << chan) ? "yes" : "no");
|
||||
seq_printf(s, "\tDCSR = %08x (%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
|
||||
dcsr, DCSR_STR(RUN), DCSR_STR(NODESC),
|
||||
DCSR_STR(STOPIRQEN), DCSR_STR(EORIRQEN),
|
||||
DCSR_STR(EORJMPEN), DCSR_STR(EORSTOPEN),
|
||||
DCSR_STR(SETCMPST), DCSR_STR(CLRCMPST),
|
||||
DCSR_STR(CMPST), DCSR_STR(EORINTR), DCSR_STR(REQPEND),
|
||||
DCSR_STR(STOPSTATE), DCSR_STR(ENDINTR),
|
||||
DCSR_STR(STARTINTR), DCSR_STR(BUSERR));
|
||||
|
||||
seq_printf(s, "\tDCMD = %08x (%s%s%s%s%s%s%sburst=%d width=%d len=%d)\n",
|
||||
dcmd,
|
||||
DCMD_STR(INCSRCADDR), DCMD_STR(INCTRGADDR),
|
||||
DCMD_STR(FLOWSRC), DCMD_STR(FLOWTRG),
|
||||
DCMD_STR(STARTIRQEN), DCMD_STR(ENDIRQEN),
|
||||
DCMD_STR(ENDIAN), burst, width, dcmd & DCMD_LENGTH);
|
||||
seq_printf(s, "\tDSADR = %08x\n", DSADR(chan));
|
||||
seq_printf(s, "\tDTADR = %08x\n", DTADR(chan));
|
||||
seq_printf(s, "\tDDADR = %08x\n", DDADR(chan));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dbg_show_state(struct seq_file *s, void *p)
|
||||
{
|
||||
/* basic device status */
|
||||
seq_puts(s, "DMA engine status\n");
|
||||
seq_printf(s, "\tChannel number: %d\n", num_dma_channels);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DBGFS_FUNC_DECL(name) \
|
||||
static int dbg_open_##name(struct inode *inode, struct file *file) \
|
||||
{ \
|
||||
return single_open(file, dbg_show_##name, inode->i_private); \
|
||||
} \
|
||||
static const struct file_operations dbg_fops_##name = { \
|
||||
.owner = THIS_MODULE, \
|
||||
.open = dbg_open_##name, \
|
||||
.llseek = seq_lseek, \
|
||||
.read = seq_read, \
|
||||
.release = single_release, \
|
||||
}
|
||||
|
||||
DBGFS_FUNC_DECL(state);
|
||||
DBGFS_FUNC_DECL(chan_state);
|
||||
DBGFS_FUNC_DECL(descriptors);
|
||||
DBGFS_FUNC_DECL(requester_chan);
|
||||
|
||||
static struct dentry *pxa_dma_dbg_alloc_chan(int ch, struct dentry *chandir)
|
||||
{
|
||||
char chan_name[11];
|
||||
struct dentry *chan, *chan_state = NULL, *chan_descr = NULL;
|
||||
struct dentry *chan_reqs = NULL;
|
||||
void *dt;
|
||||
|
||||
scnprintf(chan_name, sizeof(chan_name), "%d", ch);
|
||||
chan = debugfs_create_dir(chan_name, chandir);
|
||||
dt = (void *)ch;
|
||||
|
||||
if (chan)
|
||||
chan_state = debugfs_create_file("state", 0400, chan, dt,
|
||||
&dbg_fops_chan_state);
|
||||
if (chan_state)
|
||||
chan_descr = debugfs_create_file("descriptors", 0400, chan, dt,
|
||||
&dbg_fops_descriptors);
|
||||
if (chan_descr)
|
||||
chan_reqs = debugfs_create_file("requesters", 0400, chan, dt,
|
||||
&dbg_fops_requester_chan);
|
||||
if (!chan_reqs)
|
||||
goto err_state;
|
||||
|
||||
return chan;
|
||||
|
||||
err_state:
|
||||
debugfs_remove_recursive(chan);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void pxa_dma_init_debugfs(void)
|
||||
{
|
||||
int i;
|
||||
struct dentry *chandir;
|
||||
|
||||
dbgfs_root = debugfs_create_dir(DMA_DEBUG_NAME, NULL);
|
||||
if (IS_ERR(dbgfs_root) || !dbgfs_root)
|
||||
goto err_root;
|
||||
|
||||
dbgfs_state = debugfs_create_file("state", 0400, dbgfs_root, NULL,
|
||||
&dbg_fops_state);
|
||||
if (!dbgfs_state)
|
||||
goto err_state;
|
||||
|
||||
dbgfs_chan = kmalloc(sizeof(*dbgfs_state) * num_dma_channels,
|
||||
GFP_KERNEL);
|
||||
if (!dbgfs_chan)
|
||||
goto err_alloc;
|
||||
|
||||
chandir = debugfs_create_dir("channels", dbgfs_root);
|
||||
if (!chandir)
|
||||
goto err_chandir;
|
||||
|
||||
for (i = 0; i < num_dma_channels; i++) {
|
||||
dbgfs_chan[i] = pxa_dma_dbg_alloc_chan(i, chandir);
|
||||
if (!dbgfs_chan[i])
|
||||
goto err_chans;
|
||||
}
|
||||
|
||||
return;
|
||||
err_chans:
|
||||
err_chandir:
|
||||
kfree(dbgfs_chan);
|
||||
err_alloc:
|
||||
err_state:
|
||||
debugfs_remove_recursive(dbgfs_root);
|
||||
err_root:
|
||||
pr_err("pxa_dma: debugfs is not available\n");
|
||||
}
|
||||
|
||||
static void __exit pxa_dma_cleanup_debugfs(void)
|
||||
{
|
||||
debugfs_remove_recursive(dbgfs_root);
|
||||
}
|
||||
#else
|
||||
static inline void pxa_dma_init_debugfs(void) {}
|
||||
static inline void pxa_dma_cleanup_debugfs(void) {}
|
||||
#endif
|
||||
|
||||
int pxa_request_dma (char *name, pxa_dma_prio prio,
|
||||
void (*irq_handler)(int, void *),
|
||||
void *data)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i, found = 0;
|
||||
|
||||
/* basic sanity checks */
|
||||
if (!name || !irq_handler)
|
||||
return -EINVAL;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
do {
|
||||
/* try grabbing a DMA channel with the requested priority */
|
||||
for (i = 0; i < num_dma_channels; i++) {
|
||||
if ((dma_channels[i].prio == prio) &&
|
||||
!dma_channels[i].name &&
|
||||
!pxad_toggle_reserved_channel(i)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* if requested prio group is full, try a hier priority */
|
||||
} while (!found && prio--);
|
||||
|
||||
if (found) {
|
||||
DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
|
||||
dma_channels[i].name = name;
|
||||
dma_channels[i].irq_handler = irq_handler;
|
||||
dma_channels[i].data = data;
|
||||
} else {
|
||||
printk (KERN_WARNING "No more available DMA channels for %s\n", name);
|
||||
i = -ENODEV;
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
return i;
|
||||
}
|
||||
EXPORT_SYMBOL(pxa_request_dma);
|
||||
|
||||
void pxa_free_dma (int dma_ch)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!dma_channels[dma_ch].name) {
|
||||
printk (KERN_CRIT
|
||||
"%s: trying to free channel %d which is already freed\n",
|
||||
__func__, dma_ch);
|
||||
return;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
|
||||
dma_channels[dma_ch].name = NULL;
|
||||
pxad_toggle_reserved_channel(dma_ch);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
EXPORT_SYMBOL(pxa_free_dma);
|
||||
|
||||
static irqreturn_t dma_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
int i, dint = DINT, done = 0;
|
||||
struct dma_channel *channel;
|
||||
|
||||
while (dint) {
|
||||
i = __ffs(dint);
|
||||
dint &= (dint - 1);
|
||||
channel = &dma_channels[i];
|
||||
if (channel->name && channel->irq_handler) {
|
||||
channel->irq_handler(i, channel->data);
|
||||
done++;
|
||||
}
|
||||
}
|
||||
if (done)
|
||||
return IRQ_HANDLED;
|
||||
else
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
int __init pxa_init_dma(int irq, int num_ch)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
|
||||
if (dma_channels == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/* dma channel priorities on pxa2xx processors:
|
||||
* ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH
|
||||
* ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM
|
||||
* ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW
|
||||
*/
|
||||
for (i = 0; i < num_ch; i++) {
|
||||
DCSR(i) = 0;
|
||||
dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
|
||||
spin_lock_init(&dma_channels[i].lock);
|
||||
}
|
||||
|
||||
ret = request_irq(irq, dma_irq_handler, IRQF_SHARED, "DMA",
|
||||
dma_channels);
|
||||
if (ret) {
|
||||
printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n");
|
||||
kfree(dma_channels);
|
||||
return ret;
|
||||
}
|
||||
num_dma_channels = num_ch;
|
||||
|
||||
pxa_dma_init_debugfs();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
#ifndef __PLAT_DMA_H
|
||||
#define __PLAT_DMA_H
|
||||
|
||||
#define DMAC_REG(x) (*((volatile u32 *)(DMAC_REGS_VIRT + (x))))
|
||||
|
||||
#define DCSR(n) DMAC_REG((n) << 2)
|
||||
#define DALGN DMAC_REG(0x00a0) /* DMA Alignment Register */
|
||||
#define DINT DMAC_REG(0x00f0) /* DMA Interrupt Register */
|
||||
#define DDADR(n) DMAC_REG(0x0200 + ((n) << 4))
|
||||
#define DSADR(n) DMAC_REG(0x0204 + ((n) << 4))
|
||||
#define DTADR(n) DMAC_REG(0x0208 + ((n) << 4))
|
||||
#define DCMD(n) DMAC_REG(0x020c + ((n) << 4))
|
||||
#define DRCMR(n) DMAC_REG((((n) < 64) ? 0x0100 : 0x1100) + \
|
||||
(((n) & 0x3f) << 2))
|
||||
|
||||
#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */
|
||||
#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */
|
||||
#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
|
||||
#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */
|
||||
#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */
|
||||
#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */
|
||||
#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */
|
||||
#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */
|
||||
|
||||
#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */
|
||||
#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */
|
||||
#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */
|
||||
#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */
|
||||
#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */
|
||||
#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */
|
||||
#define DCSR_EORINTR (1 << 9) /* The end of Receive */
|
||||
|
||||
#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
|
||||
#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */
|
||||
|
||||
#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */
|
||||
#define DDADR_STOP (1 << 0) /* Stop (read / write) */
|
||||
|
||||
#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */
|
||||
#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */
|
||||
#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */
|
||||
#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */
|
||||
#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
|
||||
#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */
|
||||
#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */
|
||||
#define DCMD_BURST8 (1 << 16) /* 8 byte burst */
|
||||
#define DCMD_BURST16 (2 << 16) /* 16 byte burst */
|
||||
#define DCMD_BURST32 (3 << 16) /* 32 byte burst */
|
||||
#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */
|
||||
#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */
|
||||
#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */
|
||||
#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
|
||||
|
||||
/*
|
||||
* Descriptor structure for PXA's DMA engine
|
||||
* Note: this structure must always be aligned to a 16-byte boundary.
|
||||
*/
|
||||
|
||||
typedef struct pxa_dma_desc {
|
||||
volatile u32 ddadr; /* Points to the next descriptor + flags */
|
||||
volatile u32 dsadr; /* DSADR value for the current transfer */
|
||||
volatile u32 dtadr; /* DTADR value for the current transfer */
|
||||
volatile u32 dcmd; /* DCMD value for the current transfer */
|
||||
} pxa_dma_desc;
|
||||
|
||||
typedef enum {
|
||||
DMA_PRIO_HIGH = 0,
|
||||
DMA_PRIO_MEDIUM = 1,
|
||||
DMA_PRIO_LOW = 2
|
||||
} pxa_dma_prio;
|
||||
|
||||
/*
|
||||
* DMA registration
|
||||
*/
|
||||
|
||||
int __init pxa_init_dma(int irq, int num_ch);
|
||||
|
||||
int pxa_request_dma (char *name,
|
||||
pxa_dma_prio prio,
|
||||
void (*irq_handler)(int, void *),
|
||||
void *data);
|
||||
|
||||
void pxa_free_dma (int dma_ch);
|
||||
|
||||
/*
|
||||
* Cooperation with pxa_dma + dmaengine while there remains at least one pxa
|
||||
* driver not converted to dmaengine.
|
||||
*/
|
||||
#if defined(CONFIG_PXA_DMA)
|
||||
extern int pxad_toggle_reserved_channel(int legacy_channel);
|
||||
#else
|
||||
static inline int pxad_toggle_reserved_channel(int legacy_channel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors);
|
||||
|
||||
#endif /* __PLAT_DMA_H */
|
Loading…
Reference in New Issue
Block a user