Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit adcb8627 authored by Manuel Lauss's avatar Manuel Lauss Committed by Ralf Baechle
Browse files

MIPS: Alchemy: Convert dbdma.c to syscore_ops



Convert the PM sysdev to syscore_ops and clean up the ddma addresses a bit.

Signed-off-by: default avatarManuel Lauss <manuel.lauss@googlemail.com>
To: Linux-MIPS <linux-mips@linux-mips.org>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Wolfgang Grandegger <wg@grandegger.com>
Patchwork: https://patchwork.linux-mips.org/patch/2351/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 4b5c82b5
Loading
Loading
Loading
Loading
+45 −78
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/sysdev.h>
#include <linux/syscore_ops.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>

@@ -58,7 +58,8 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
/* I couldn't find a macro that did this... */
#define ALIGN_ADDR(x, a)	((((u32)(x)) + (a-1)) & ~(a-1))

static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
static dbdma_global_t *dbdma_gptr =
			(dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
static int dbdma_initialized;

static dbdev_tab_t dbdev_tab[] = {
@@ -299,7 +300,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
	if (ctp != NULL) {
		memset(ctp, 0, sizeof(chan_tab_t));
		ctp->chan_index = chan = i;
		dcp = DDMA_CHANNEL_BASE;
		dcp = KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
		dcp += (0x0100 * chan);
		ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
		cp = (au1x_dma_chan_t *)dcp;
@@ -958,105 +959,75 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)
}


struct alchemy_dbdma_sysdev {
	struct sys_device sysdev;
	u32 pm_regs[NUM_DBDMA_CHANS + 1][6];
};
static unsigned long alchemy_dbdma_pm_data[NUM_DBDMA_CHANS + 1][6];

static int alchemy_dbdma_suspend(struct sys_device *dev,
				 pm_message_t state)
static int alchemy_dbdma_suspend(void)
{
	struct alchemy_dbdma_sysdev *sdev =
		container_of(dev, struct alchemy_dbdma_sysdev, sysdev);
	int i;
	u32 addr;
	void __iomem *addr;

	addr = DDMA_GLOBAL_BASE;
	sdev->pm_regs[0][0] = au_readl(addr + 0x00);
	sdev->pm_regs[0][1] = au_readl(addr + 0x04);
	sdev->pm_regs[0][2] = au_readl(addr + 0x08);
	sdev->pm_regs[0][3] = au_readl(addr + 0x0c);
	addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
	alchemy_dbdma_pm_data[0][0] = __raw_readl(addr + 0x00);
	alchemy_dbdma_pm_data[0][1] = __raw_readl(addr + 0x04);
	alchemy_dbdma_pm_data[0][2] = __raw_readl(addr + 0x08);
	alchemy_dbdma_pm_data[0][3] = __raw_readl(addr + 0x0c);

	/* save channel configurations */
	for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) {
		sdev->pm_regs[i][0] = au_readl(addr + 0x00);
		sdev->pm_regs[i][1] = au_readl(addr + 0x04);
		sdev->pm_regs[i][2] = au_readl(addr + 0x08);
		sdev->pm_regs[i][3] = au_readl(addr + 0x0c);
		sdev->pm_regs[i][4] = au_readl(addr + 0x10);
		sdev->pm_regs[i][5] = au_readl(addr + 0x14);
	addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
	for (i = 1; i <= NUM_DBDMA_CHANS; i++) {
		alchemy_dbdma_pm_data[i][0] = __raw_readl(addr + 0x00);
		alchemy_dbdma_pm_data[i][1] = __raw_readl(addr + 0x04);
		alchemy_dbdma_pm_data[i][2] = __raw_readl(addr + 0x08);
		alchemy_dbdma_pm_data[i][3] = __raw_readl(addr + 0x0c);
		alchemy_dbdma_pm_data[i][4] = __raw_readl(addr + 0x10);
		alchemy_dbdma_pm_data[i][5] = __raw_readl(addr + 0x14);

		/* halt channel */
		au_writel(sdev->pm_regs[i][0] & ~1, addr + 0x00);
		au_sync();
		while (!(au_readl(addr + 0x14) & 1))
			au_sync();
		__raw_writel(alchemy_dbdma_pm_data[i][0] & ~1, addr + 0x00);
		wmb();
		while (!(__raw_readl(addr + 0x14) & 1))
			wmb();

		addr += 0x100;	/* next channel base */
	}
	/* disable channel interrupts */
	au_writel(0, DDMA_GLOBAL_BASE + 0x0c);
	au_sync();
	addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
	__raw_writel(0, addr + 0x0c);
	wmb();

	return 0;
}

static int alchemy_dbdma_resume(struct sys_device *dev)
static void alchemy_dbdma_resume(void)
{
	struct alchemy_dbdma_sysdev *sdev =
		container_of(dev, struct alchemy_dbdma_sysdev, sysdev);
	int i;
	u32 addr;
	void __iomem *addr;

	addr = DDMA_GLOBAL_BASE;
	au_writel(sdev->pm_regs[0][0], addr + 0x00);
	au_writel(sdev->pm_regs[0][1], addr + 0x04);
	au_writel(sdev->pm_regs[0][2], addr + 0x08);
	au_writel(sdev->pm_regs[0][3], addr + 0x0c);
	addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
	__raw_writel(alchemy_dbdma_pm_data[0][0], addr + 0x00);
	__raw_writel(alchemy_dbdma_pm_data[0][1], addr + 0x04);
	__raw_writel(alchemy_dbdma_pm_data[0][2], addr + 0x08);
	__raw_writel(alchemy_dbdma_pm_data[0][3], addr + 0x0c);

	/* restore channel configurations */
	for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) {
		au_writel(sdev->pm_regs[i][0], addr + 0x00);
		au_writel(sdev->pm_regs[i][1], addr + 0x04);
		au_writel(sdev->pm_regs[i][2], addr + 0x08);
		au_writel(sdev->pm_regs[i][3], addr + 0x0c);
		au_writel(sdev->pm_regs[i][4], addr + 0x10);
		au_writel(sdev->pm_regs[i][5], addr + 0x14);
		au_sync();
	addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
	for (i = 1; i <= NUM_DBDMA_CHANS; i++) {
		__raw_writel(alchemy_dbdma_pm_data[i][0], addr + 0x00);
		__raw_writel(alchemy_dbdma_pm_data[i][1], addr + 0x04);
		__raw_writel(alchemy_dbdma_pm_data[i][2], addr + 0x08);
		__raw_writel(alchemy_dbdma_pm_data[i][3], addr + 0x0c);
		__raw_writel(alchemy_dbdma_pm_data[i][4], addr + 0x10);
		__raw_writel(alchemy_dbdma_pm_data[i][5], addr + 0x14);
		wmb();
		addr += 0x100;	/* next channel base */
	}

	return 0;
}

static struct sysdev_class alchemy_dbdma_sysdev_class = {
	.name		= "dbdma",
static struct syscore_ops alchemy_dbdma_syscore_ops = {
	.suspend	= alchemy_dbdma_suspend,
	.resume		= alchemy_dbdma_resume,
};

static int __init alchemy_dbdma_sysdev_init(void)
{
	struct alchemy_dbdma_sysdev *sdev;
	int ret;

	ret = sysdev_class_register(&alchemy_dbdma_sysdev_class);
	if (ret)
		return ret;

	sdev = kzalloc(sizeof(struct alchemy_dbdma_sysdev), GFP_KERNEL);
	if (!sdev)
		return -ENOMEM;

	sdev->sysdev.id = -1;
	sdev->sysdev.cls = &alchemy_dbdma_sysdev_class;
	ret = sysdev_register(&sdev->sysdev);
	if (ret)
		kfree(sdev);

	return ret;
}

static int __init au1xxx_dbdma_init(void)
{
	int irq_nr, ret;
@@ -1084,11 +1055,7 @@ static int __init au1xxx_dbdma_init(void)
	else {
		dbdma_initialized = 1;
		printk(KERN_INFO "Alchemy DBDMA initialized\n");
		ret = alchemy_dbdma_sysdev_init();
		if (ret) {
			printk(KERN_ERR "DBDMA PM init failed\n");
			ret = 0;
		}
		register_syscore_ops(&alchemy_dbdma_syscore_ops);
	}

	return ret;
+2 −2
Original line number Diff line number Diff line
@@ -635,6 +635,8 @@ enum soc_au1200_ints {

#define AU1000_IC0_PHYS_ADDR		0x10400000 /* 01234 */
#define AU1000_IC1_PHYS_ADDR		0x11800000 /* 01234 */
#define AU1550_DBDMA_PHYS_ADDR		0x14002000 /* 34 */
#define AU1550_DBDMA_CONF_PHYS_ADDR	0x14003000 /* 34 */


#ifdef CONFIG_SOC_AU1000
@@ -761,7 +763,6 @@ enum soc_au1200_ints {
#define	UART3_PHYS_ADDR		0x11400000
#define GPIO2_PHYS_ADDR		0x11700000
#define	SYS_PHYS_ADDR		0x11900000
#define	DDMA_PHYS_ADDR		0x14002000
#define PE_PHYS_ADDR		0x14008000
#define PSC0_PHYS_ADDR		0x11A00000
#define PSC1_PHYS_ADDR		0x11B00000
@@ -789,7 +790,6 @@ enum soc_au1200_ints {
#define	UART1_PHYS_ADDR		0x11200000
#define GPIO2_PHYS_ADDR		0x11700000
#define	SYS_PHYS_ADDR		0x11900000
#define	DDMA_PHYS_ADDR		0x14002000
#define PSC0_PHYS_ADDR	 	0x11A00000
#define PSC1_PHYS_ADDR	 	0x11B00000
#define SD0_PHYS_ADDR		0x10600000
+0 −8
Original line number Diff line number Diff line
@@ -37,14 +37,6 @@

#ifndef _LANGUAGE_ASSEMBLY

/*
 * The DMA base addresses.
 * The channels are every 256 bytes (0x0100) from the channel 0 base.
 * Interrupt status/enable is bits 15:0 for channels 15 to zero.
 */
#define DDMA_GLOBAL_BASE	0xb4003000
#define DDMA_CHANNEL_BASE	0xb4002000

typedef volatile struct dbdma_global {
	u32	ddma_config;
	u32	ddma_intstat;