[PATCH 02/13] powerpc/5200: LocalPlus driver: use SCLPC register structure

Roman Fietze roman.fietze at telemotive.de
Tue Dec 22 17:59:23 EST 2009


Signed-off-by: Roman Fietze <roman.fietze at telemotive.de>
---
 arch/powerpc/include/asm/mpc52xx.h            |   24 ++++++++
 arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c |   79 +++++++++++--------------
 2 files changed, 59 insertions(+), 44 deletions(-)

diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h
index b664ce7..57f8335 100644
--- a/arch/powerpc/include/asm/mpc52xx.h
+++ b/arch/powerpc/include/asm/mpc52xx.h
@@ -193,6 +193,30 @@ struct mpc52xx_xlb {
 #define MPC52xx_XLB_CFG_PLDIS		(1 << 31)
 #define MPC52xx_XLB_CFG_SNOOP		(1 << 15)
 
+/* SCLPC */
+struct mpc52xx_sclpc {
+	union {
+		u8 restart;	/* 0x00 restart bit */
+		u32 packet_size; /* 0x00 packet size register */
+	} packet_size;
+	u32 start_address;	/* 0x04	start Address register */
+	u32 control;		/* 0x08	control register */
+	u32 enable;		/* 0x0C	enable register */
+	u32 unused0;		/* 0x10 */
+	union {
+		u8 status;	/* 0x14	status register bits */
+		u32 bytes_done; /* 0x14	bytes done register bits, read only */
+	} bytes_done_status;
+
+	u32 reserved1[(0x40-0x18) / sizeof(u32)];	/* 0x18 .. 0x3c */
+
+	u32 fifo_data;		/* 0x40	FIFO data word register */
+	u32 fifo_status;	/* 0x44	FIFO status register */
+	u8 fifo_control;	/* 0x48	FIFO control register */
+	u8 reserved2[3];
+	u32 fifo_alarm;		/* 0x4C	FIFO alarm register */
+};
+
 /* Clock Distribution control */
 struct mpc52xx_cdm {
 	u32 jtag_id;		/* CDM + 0x00  reg0 read only */
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index 4c84aa5..2763d5e 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -27,20 +27,10 @@ MODULE_AUTHOR("Grant Likely <grant.likely at secretlab.ca>");
 MODULE_DESCRIPTION("MPC5200 LocalPlus FIFO device driver");
 MODULE_LICENSE("GPL");
 
-#define LPBFIFO_REG_PACKET_SIZE		(0x00)
-#define LPBFIFO_REG_START_ADDRESS	(0x04)
-#define LPBFIFO_REG_CONTROL		(0x08)
-#define LPBFIFO_REG_ENABLE		(0x0C)
-#define LPBFIFO_REG_BYTES_DONE_STATUS	(0x14)
-#define LPBFIFO_REG_FIFO_DATA		(0x40)
-#define LPBFIFO_REG_FIFO_STATUS		(0x44)
-#define LPBFIFO_REG_FIFO_CONTROL	(0x48)
-#define LPBFIFO_REG_FIFO_ALARM		(0x4C)
-
 struct mpc52xx_lpbfifo {
 	struct device *dev;
 	phys_addr_t regs_phys;
-	void __iomem *regs;
+	struct mpc52xx_sclpc __iomem *regs;
 	int irq;
 	spinlock_t lock;
 
@@ -72,10 +62,10 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
 	int poll_dma = req->flags & MPC52XX_LPBFIFO_FLAG_POLL_DMA;
 
 	/* Set and clear the reset bits; is good practice in User Manual */
-	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+	out_be32(&lpbfifo.regs->enable, 0x01010000);
 
 	/* set master enable bit */
-	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000001);
+	out_be32(&lpbfifo.regs->enable, 0x00000001);
 	if (!dma) {
 		/* While the FIFO can be setup for transfer sizes as large as
 		 * 16M-1, the FIFO itself is only 512 bytes deep and it does
@@ -91,14 +81,14 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
 
 		/* Load the FIFO with data */
 		if (write) {
-			reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
+			reg = &lpbfifo.regs->fifo_data;
 			data = req->data + req->pos;
 			for (i = 0; i < transfer_size; i += 4)
 				out_be32(reg, *data++);
 		}
 
 		/* Unmask both error and completion irqs */
-		out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000301);
+		out_be32(&lpbfifo.regs->enable, 0x00000301);
 	} else {
 		/* Choose the correct direction
 		 *
@@ -108,12 +98,12 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
 		 * is a risk of DMA not transferring the last chunk of data
 		 */
 		if (write) {
-			out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1e4);
-			out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 7);
+			out_be32(&lpbfifo.regs->fifo_alarm, 0x1e4);
+			out_8(&lpbfifo.regs->fifo_control, 7);
 			lpbfifo.bcom_cur_task = lpbfifo.bcom_tx_task;
 		} else {
-			out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1ff);
-			out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 0);
+			out_be32(&lpbfifo.regs->fifo_alarm, 0x1ff);
+			out_8(&lpbfifo.regs->fifo_control, 0);
 			lpbfifo.bcom_cur_task = lpbfifo.bcom_rx_task;
 
 			if (poll_dma) {
@@ -155,21 +145,21 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
 		/* Unmask irqs */
 		if (write && (!poll_dma))
 			bit_fields |= 0x00000100; /* completion irq too */
-		out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, bit_fields);
+		out_be32(&lpbfifo.regs->enable, bit_fields);
 	}
 
 	/* Set transfer size, width, chip select and READ mode */
-	out_be32(lpbfifo.regs + LPBFIFO_REG_START_ADDRESS,
+	out_be32(&lpbfifo.regs->start_address,
 		 req->offset + req->pos);
-	out_be32(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, transfer_size);
+	out_be32(&lpbfifo.regs->packet_size.packet_size, transfer_size);
 
 	bit_fields = req->cs << 24 | 0x000008;
 	if (!write)
 		bit_fields |= 0x010000;	/* read mode */
-	out_be32(lpbfifo.regs + LPBFIFO_REG_CONTROL, bit_fields);
+	out_be32(&lpbfifo.regs->control, bit_fields);
 
 	/* Kick it off */
-	out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
+	out_8(&lpbfifo.regs->packet_size.restart, 0x01);
 	if (dma)
 		bcom_enable(lpbfifo.bcom_cur_task);
 }
@@ -218,7 +208,7 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
 static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id)
 {
 	struct mpc52xx_lpbfifo_request *req;
-	u32 status = in_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
+	u32 status = in_8(&lpbfifo.regs->bytes_done_status.status);
 	void __iomem *reg;
 	u32 *data;
 	int count, i;
@@ -253,18 +243,18 @@ static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id)
 
 	/* check abort bit */
 	if (status & 0x10) {
-		out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+		out_be32(&lpbfifo.regs->enable, 0x01010000);
 		do_callback = 1;
 		goto out;
 	}
 
 	/* Read result from hardware */
-	count = in_be32(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
+	count = in_be32(&lpbfifo.regs->bytes_done_status.bytes_done);
 	count &= 0x00ffffff;
 
 	if (!dma && !write) {
 		/* copy the data out of the FIFO */
-		reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
+		reg = &lpbfifo.regs->fifo_data;
 		data = req->data + req->pos;
 		for (i = 0; i < count; i += 4)
 			*data++ = in_be32(reg);
@@ -281,7 +271,7 @@ static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id)
 
 out:
 	/* Clear the IRQ */
-	out_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS, 0x01);
+	out_8(&lpbfifo.regs->bytes_done_status.status, 0x01);
 
 	if (dma && (status & 0x11)) {
 		/*
@@ -379,11 +369,11 @@ void mpc52xx_lpbfifo_poll(void)
 	int write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
 
 	/*
-	 * For more information, see comments on the "Fat Lady"
+	 * For more information, see comments on the "Fat Lady" 
 	 */
 	if (dma && write)
 		mpc52xx_lpbfifo_irq(0, NULL);
-	else
+	else 
 		mpc52xx_lpbfifo_bcom_irq(0, NULL);
 }
 EXPORT_SYMBOL(mpc52xx_lpbfifo_poll);
@@ -429,7 +419,7 @@ void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req)
 		/* Put it into reset and clear the state */
 		bcom_gen_bd_rx_reset(lpbfifo.bcom_rx_task);
 		bcom_gen_bd_tx_reset(lpbfifo.bcom_tx_task);
-		out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+		out_be32(&lpbfifo.regs->enable, 0x01010000);
 		lpbfifo.req = NULL;
 	}
 	spin_unlock_irqrestore(&lpbfifo.lock, flags);
@@ -459,19 +449,19 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
 	spin_lock_init(&lpbfifo.lock);
 
 	/* Put FIFO into reset */
-	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+	out_be32(&lpbfifo.regs->enable, 0x01010000);
 
-	/* Register the interrupt handler */
+	/* register the interrupt handler */
 	rc = request_irq(lpbfifo.irq, mpc52xx_lpbfifo_irq, 0,
 			 "mpc52xx-lpbfifo", &lpbfifo);
 	if (rc)
 		goto err_irq;
 
 	/* Request the Bestcomm receive (fifo --> memory) task and IRQ */
-	lpbfifo.bcom_rx_task =
-		bcom_gen_bd_rx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
-				    BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC,
-				    16*1024*1024);
+	lpbfifo.bcom_rx_task = bcom_gen_bd_rx_init(2,
+						   res.start + offsetof(struct mpc52xx_sclpc, fifo_data),
+						   BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC,
+						   16*1024*1024);
 	if (!lpbfifo.bcom_rx_task)
 		goto err_bcom_rx;
 
@@ -482,9 +472,10 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
 		goto err_bcom_rx_irq;
 
 	/* Request the Bestcomm transmit (memory --> fifo) task and IRQ */
-	lpbfifo.bcom_tx_task =
-		bcom_gen_bd_tx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
-				    BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC);
+	lpbfifo.bcom_tx_task = bcom_gen_bd_tx_init(2,
+						   res.start + offsetof(struct mpc52xx_sclpc, fifo_data),
+						   BCOM_INITIATOR_SCLPC,
+						   BCOM_IPR_SCLPC);
 	if (!lpbfifo.bcom_tx_task)
 		goto err_bcom_tx;
 
@@ -511,12 +502,12 @@ static int __devexit mpc52xx_lpbfifo_remove(struct of_device *op)
 		return 0;
 
 	/* Put FIFO in reset */
-	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+	out_be32(&lpbfifo.regs->enable, 0x01010000);
 
-	/* Release the bestcomm transmit task */
+	/* release the bestcomm transmit task */
 	free_irq(bcom_get_task_irq(lpbfifo.bcom_tx_task), &lpbfifo);
 	bcom_gen_bd_tx_release(lpbfifo.bcom_tx_task);
-
+	
 	/* Release the bestcomm receive task */
 	free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
 	bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
-- 
1.6.5.5


-- 
Roman Fietze                Telemotive AG Büro Mühlhausen
Breitwiesen                              73347 Mühlhausen
Tel.: +49(0)7335/18493-45        http://www.telemotive.de


More information about the Linuxppc-dev mailing list