aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/fsl_rio.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/powerpc/sysdev/fsl_rio.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/powerpc/sysdev/fsl_rio.c')
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c380
1 files changed, 225 insertions, 155 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 3017532319c8..b3fd081d56f5 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -10,7 +10,7 @@
10 * - Added Port-Write message handling 10 * - Added Port-Write message handling
11 * - Added Machine Check exception handling 11 * - Added Machine Check exception handling
12 * 12 *
13 * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc. 13 * Copyright (C) 2007, 2008, 2010 Freescale Semiconductor, Inc.
14 * Zhang Wei <wei.zhang@freescale.com> 14 * Zhang Wei <wei.zhang@freescale.com>
15 * 15 *
16 * Copyright 2005 MontaVista Software, Inc. 16 * Copyright 2005 MontaVista Software, Inc.
@@ -47,14 +47,33 @@
47#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) 47#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq)
48#define IRQ_RIO_PW(m) (((struct rio_priv *)(m->priv))->pwirq) 48#define IRQ_RIO_PW(m) (((struct rio_priv *)(m->priv))->pwirq)
49 49
50#define IPWSR_CLEAR 0x98
51#define OMSR_CLEAR 0x1cb3
52#define IMSR_CLEAR 0x491
53#define IDSR_CLEAR 0x91
54#define ODSR_CLEAR 0x1c00
55#define LTLEECSR_ENABLE_ALL 0xFFC000FC
56#define ESCSR_CLEAR 0x07120204
57
58#define RIO_PORT1_EDCSR 0x0640
59#define RIO_PORT2_EDCSR 0x0680
60#define RIO_PORT1_IECSR 0x10130
61#define RIO_PORT2_IECSR 0x101B0
62#define RIO_IM0SR 0x13064
63#define RIO_IM1SR 0x13164
64#define RIO_OM0SR 0x13004
65#define RIO_OM1SR 0x13104
66
50#define RIO_ATMU_REGS_OFFSET 0x10c00 67#define RIO_ATMU_REGS_OFFSET 0x10c00
51#define RIO_P_MSG_REGS_OFFSET 0x11000 68#define RIO_P_MSG_REGS_OFFSET 0x11000
52#define RIO_S_MSG_REGS_OFFSET 0x13000 69#define RIO_S_MSG_REGS_OFFSET 0x13000
70#define RIO_GCCSR 0x13c
53#define RIO_ESCSR 0x158 71#define RIO_ESCSR 0x158
72#define RIO_PORT2_ESCSR 0x178
54#define RIO_CCSR 0x15c 73#define RIO_CCSR 0x15c
55#define RIO_LTLEDCSR 0x0608 74#define RIO_LTLEDCSR 0x0608
56#define RIO_LTLEDCSR_IER 0x80000000 75#define RIO_LTLEDCSR_IER 0x80000000
57#define RIO_LTLEDCSR_PRT 0x01000000 76#define RIO_LTLEDCSR_PRT 0x01000000
58#define RIO_LTLEECSR 0x060c 77#define RIO_LTLEECSR 0x060c
59#define RIO_EPWISR 0x10010 78#define RIO_EPWISR 0x10010
60#define RIO_ISR_AACR 0x10120 79#define RIO_ISR_AACR 0x10120
@@ -87,6 +106,12 @@
87#define RIO_IPWSR_PWD 0x00000008 106#define RIO_IPWSR_PWD 0x00000008
88#define RIO_IPWSR_PWB 0x00000004 107#define RIO_IPWSR_PWB 0x00000004
89 108
109/* EPWISR Error match value */
110#define RIO_EPWISR_PINT1 0x80000000
111#define RIO_EPWISR_PINT2 0x40000000
112#define RIO_EPWISR_MU 0x00000002
113#define RIO_EPWISR_PW 0x00000001
114
90#define RIO_MSG_DESC_SIZE 32 115#define RIO_MSG_DESC_SIZE 32
91#define RIO_MSG_BUFFER_SIZE 4096 116#define RIO_MSG_BUFFER_SIZE 4096
92#define RIO_MIN_TX_RING_SIZE 2 117#define RIO_MIN_TX_RING_SIZE 2
@@ -117,44 +142,59 @@ struct rio_atmu_regs {
117}; 142};
118 143
119struct rio_msg_regs { 144struct rio_msg_regs {
120 u32 omr; 145 u32 omr; /* 0xD_3000 - Outbound message 0 mode register */
121 u32 osr; 146 u32 osr; /* 0xD_3004 - Outbound message 0 status register */
122 u32 pad1; 147 u32 pad1;
123 u32 odqdpar; 148 u32 odqdpar; /* 0xD_300C - Outbound message 0 descriptor queue
149 dequeue pointer address register */
124 u32 pad2; 150 u32 pad2;
125 u32 osar; 151 u32 osar; /* 0xD_3014 - Outbound message 0 source address
126 u32 odpr; 152 register */
127 u32 odatr; 153 u32 odpr; /* 0xD_3018 - Outbound message 0 destination port
128 u32 odcr; 154 register */
155 u32 odatr; /* 0xD_301C - Outbound message 0 destination attributes
156 Register*/
157 u32 odcr; /* 0xD_3020 - Outbound message 0 double-word count
158 register */
129 u32 pad3; 159 u32 pad3;
130 u32 odqepar; 160 u32 odqepar; /* 0xD_3028 - Outbound message 0 descriptor queue
161 enqueue pointer address register */
131 u32 pad4[13]; 162 u32 pad4[13];
132 u32 imr; 163 u32 imr; /* 0xD_3060 - Inbound message 0 mode register */
133 u32 isr; 164 u32 isr; /* 0xD_3064 - Inbound message 0 status register */
134 u32 pad5; 165 u32 pad5;
135 u32 ifqdpar; 166 u32 ifqdpar; /* 0xD_306C - Inbound message 0 frame queue dequeue
167 pointer address register*/
136 u32 pad6; 168 u32 pad6;
137 u32 ifqepar; 169 u32 ifqepar; /* 0xD_3074 - Inbound message 0 frame queue enqueue
170 pointer address register */
138 u32 pad7[226]; 171 u32 pad7[226];
139 u32 odmr; 172 u32 odmr; /* 0xD_3400 - Outbound doorbell mode register */
140 u32 odsr; 173 u32 odsr; /* 0xD_3404 - Outbound doorbell status register */
141 u32 res0[4]; 174 u32 res0[4];
142 u32 oddpr; 175 u32 oddpr; /* 0xD_3418 - Outbound doorbell destination port
143 u32 oddatr; 176 register */
177 u32 oddatr; /* 0xD_341c - Outbound doorbell destination attributes
178 register */
144 u32 res1[3]; 179 u32 res1[3];
145 u32 odretcr; 180 u32 odretcr; /* 0xD_342C - Outbound doorbell retry error threshold
181 configuration register */
146 u32 res2[12]; 182 u32 res2[12];
147 u32 dmr; 183 u32 dmr; /* 0xD_3460 - Inbound doorbell mode register */
148 u32 dsr; 184 u32 dsr; /* 0xD_3464 - Inbound doorbell status register */
149 u32 pad8; 185 u32 pad8;
150 u32 dqdpar; 186 u32 dqdpar; /* 0xD_346C - Inbound doorbell queue dequeue Pointer
187 address register */
151 u32 pad9; 188 u32 pad9;
152 u32 dqepar; 189 u32 dqepar; /* 0xD_3474 - Inbound doorbell Queue enqueue pointer
190 address register */
153 u32 pad10[26]; 191 u32 pad10[26];
154 u32 pwmr; 192 u32 pwmr; /* 0xD_34E0 - Inbound port-write mode register */
155 u32 pwsr; 193 u32 pwsr; /* 0xD_34E4 - Inbound port-write status register */
156 u32 epwqbar; 194 u32 epwqbar; /* 0xD_34E8 - Extended Port-Write Queue Base Address
157 u32 pwqbar; 195 register */
196 u32 pwqbar; /* 0xD_34EC - Inbound port-write queue base address
197 register */
158}; 198};
159 199
160struct rio_tx_desc { 200struct rio_tx_desc {
@@ -241,35 +281,32 @@ struct rio_priv {
241static void __iomem *rio_regs_win; 281static void __iomem *rio_regs_win;
242 282
243#ifdef CONFIG_E500 283#ifdef CONFIG_E500
244static int (*saved_mcheck_exception)(struct pt_regs *regs); 284int fsl_rio_mcheck_exception(struct pt_regs *regs)
245
246static int fsl_rio_mcheck_exception(struct pt_regs *regs)
247{ 285{
248 const struct exception_table_entry *entry = NULL; 286 const struct exception_table_entry *entry;
249 unsigned long reason = mfspr(SPRN_MCSR); 287 unsigned long reason;
250 288
251 if (reason & MCSR_BUS_RBERR) { 289 if (!rio_regs_win)
252 reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR)); 290 return 0;
253 if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) { 291
254 /* Check if we are prepared to handle this fault */ 292 reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
255 entry = search_exception_tables(regs->nip); 293 if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
256 if (entry) { 294 /* Check if we are prepared to handle this fault */
257 pr_debug("RIO: %s - MC Exception handled\n", 295 entry = search_exception_tables(regs->nip);
258 __func__); 296 if (entry) {
259 out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 297 pr_debug("RIO: %s - MC Exception handled\n",
260 0); 298 __func__);
261 regs->msr |= MSR_RI; 299 out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR),
262 regs->nip = entry->fixup; 300 0);
263 return 1; 301 regs->msr |= MSR_RI;
264 } 302 regs->nip = entry->fixup;
303 return 1;
265 } 304 }
266 } 305 }
267 306
268 if (saved_mcheck_exception) 307 return 0;
269 return saved_mcheck_exception(regs);
270 else
271 return cur_cpu_spec->machine_check(regs);
272} 308}
309EXPORT_SYMBOL_GPL(fsl_rio_mcheck_exception);
273#endif 310#endif
274 311
275/** 312/**
@@ -463,7 +500,7 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
463} 500}
464 501
465/** 502/**
466 * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue 503 * fsl_add_outb_message - Add message to the MPC85xx outbound message queue
467 * @mport: Master port with outbound message queue 504 * @mport: Master port with outbound message queue
468 * @rdev: Target of outbound message 505 * @rdev: Target of outbound message
469 * @mbox: Outbound mailbox 506 * @mbox: Outbound mailbox
@@ -473,8 +510,8 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
473 * Adds the @buffer message to the MPC85xx outbound message queue. Returns 510 * Adds the @buffer message to the MPC85xx outbound message queue. Returns
474 * %0 on success or %-EINVAL on failure. 511 * %0 on success or %-EINVAL on failure.
475 */ 512 */
476int 513static int
477rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox, 514fsl_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
478 void *buffer, size_t len) 515 void *buffer, size_t len)
479{ 516{
480 struct rio_priv *priv = mport->priv; 517 struct rio_priv *priv = mport->priv;
@@ -483,9 +520,8 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
483 + priv->msg_tx_ring.tx_slot; 520 + priv->msg_tx_ring.tx_slot;
484 int ret = 0; 521 int ret = 0;
485 522
486 pr_debug 523 pr_debug("RIO: fsl_add_outb_message(): destid %4.4x mbox %d buffer " \
487 ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x len %8.8x\n", 524 "%8.8x len %8.8x\n", rdev->destid, mbox, (int)buffer, len);
488 rdev->destid, mbox, (int)buffer, len);
489 525
490 if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) { 526 if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) {
491 ret = -EINVAL; 527 ret = -EINVAL;
@@ -535,8 +571,6 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
535 return ret; 571 return ret;
536} 572}
537 573
538EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
539
540/** 574/**
541 * fsl_rio_tx_handler - MPC85xx outbound message interrupt handler 575 * fsl_rio_tx_handler - MPC85xx outbound message interrupt handler
542 * @irq: Linux interrupt number 576 * @irq: Linux interrupt number
@@ -581,7 +615,7 @@ fsl_rio_tx_handler(int irq, void *dev_instance)
581} 615}
582 616
583/** 617/**
584 * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox 618 * fsl_open_outb_mbox - Initialize MPC85xx outbound mailbox
585 * @mport: Master port implementing the outbound message unit 619 * @mport: Master port implementing the outbound message unit
586 * @dev_id: Device specific pointer to pass on event 620 * @dev_id: Device specific pointer to pass on event
587 * @mbox: Mailbox to open 621 * @mbox: Mailbox to open
@@ -591,7 +625,8 @@ fsl_rio_tx_handler(int irq, void *dev_instance)
591 * and enables the outbound message unit. Returns %0 on success and 625 * and enables the outbound message unit. Returns %0 on success and
592 * %-EINVAL or %-ENOMEM on failure. 626 * %-EINVAL or %-ENOMEM on failure.
593 */ 627 */
594int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) 628static int
629fsl_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
595{ 630{
596 int i, j, rc = 0; 631 int i, j, rc = 0;
597 struct rio_priv *priv = mport->priv; 632 struct rio_priv *priv = mport->priv;
@@ -687,14 +722,14 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
687} 722}
688 723
689/** 724/**
690 * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox 725 * fsl_close_outb_mbox - Shut down MPC85xx outbound mailbox
691 * @mport: Master port implementing the outbound message unit 726 * @mport: Master port implementing the outbound message unit
692 * @mbox: Mailbox to close 727 * @mbox: Mailbox to close
693 * 728 *
694 * Disables the outbound message unit, free all buffers, and 729 * Disables the outbound message unit, free all buffers, and
695 * frees the outbound message interrupt. 730 * frees the outbound message interrupt.
696 */ 731 */
697void rio_close_outb_mbox(struct rio_mport *mport, int mbox) 732static void fsl_close_outb_mbox(struct rio_mport *mport, int mbox)
698{ 733{
699 struct rio_priv *priv = mport->priv; 734 struct rio_priv *priv = mport->priv;
700 /* Disable inbound message unit */ 735 /* Disable inbound message unit */
@@ -751,7 +786,7 @@ fsl_rio_rx_handler(int irq, void *dev_instance)
751} 786}
752 787
753/** 788/**
754 * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox 789 * fsl_open_inb_mbox - Initialize MPC85xx inbound mailbox
755 * @mport: Master port implementing the inbound message unit 790 * @mport: Master port implementing the inbound message unit
756 * @dev_id: Device specific pointer to pass on event 791 * @dev_id: Device specific pointer to pass on event
757 * @mbox: Mailbox to open 792 * @mbox: Mailbox to open
@@ -761,7 +796,8 @@ fsl_rio_rx_handler(int irq, void *dev_instance)
761 * and enables the inbound message unit. Returns %0 on success 796 * and enables the inbound message unit. Returns %0 on success
762 * and %-EINVAL or %-ENOMEM on failure. 797 * and %-EINVAL or %-ENOMEM on failure.
763 */ 798 */
764int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) 799static int
800fsl_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
765{ 801{
766 int i, rc = 0; 802 int i, rc = 0;
767 struct rio_priv *priv = mport->priv; 803 struct rio_priv *priv = mport->priv;
@@ -825,14 +861,14 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
825} 861}
826 862
827/** 863/**
828 * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox 864 * fsl_close_inb_mbox - Shut down MPC85xx inbound mailbox
829 * @mport: Master port implementing the inbound message unit 865 * @mport: Master port implementing the inbound message unit
830 * @mbox: Mailbox to close 866 * @mbox: Mailbox to close
831 * 867 *
832 * Disables the inbound message unit, free all buffers, and 868 * Disables the inbound message unit, free all buffers, and
833 * frees the inbound message interrupt. 869 * frees the inbound message interrupt.
834 */ 870 */
835void rio_close_inb_mbox(struct rio_mport *mport, int mbox) 871static void fsl_close_inb_mbox(struct rio_mport *mport, int mbox)
836{ 872{
837 struct rio_priv *priv = mport->priv; 873 struct rio_priv *priv = mport->priv;
838 /* Disable inbound message unit */ 874 /* Disable inbound message unit */
@@ -847,7 +883,7 @@ void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
847} 883}
848 884
849/** 885/**
850 * rio_hw_add_inb_buffer - Add buffer to the MPC85xx inbound message queue 886 * fsl_add_inb_buffer - Add buffer to the MPC85xx inbound message queue
851 * @mport: Master port implementing the inbound message unit 887 * @mport: Master port implementing the inbound message unit
852 * @mbox: Inbound mailbox number 888 * @mbox: Inbound mailbox number
853 * @buf: Buffer to add to inbound queue 889 * @buf: Buffer to add to inbound queue
@@ -855,12 +891,12 @@ void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
855 * Adds the @buf buffer to the MPC85xx inbound message queue. Returns 891 * Adds the @buf buffer to the MPC85xx inbound message queue. Returns
856 * %0 on success or %-EINVAL on failure. 892 * %0 on success or %-EINVAL on failure.
857 */ 893 */
858int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf) 894static int fsl_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
859{ 895{
860 int rc = 0; 896 int rc = 0;
861 struct rio_priv *priv = mport->priv; 897 struct rio_priv *priv = mport->priv;
862 898
863 pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n", 899 pr_debug("RIO: fsl_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
864 priv->msg_rx_ring.rx_slot); 900 priv->msg_rx_ring.rx_slot);
865 901
866 if (priv->msg_rx_ring.virt_buffer[priv->msg_rx_ring.rx_slot]) { 902 if (priv->msg_rx_ring.virt_buffer[priv->msg_rx_ring.rx_slot]) {
@@ -879,17 +915,15 @@ int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
879 return rc; 915 return rc;
880} 916}
881 917
882EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
883
884/** 918/**
885 * rio_hw_get_inb_message - Fetch inbound message from the MPC85xx message unit 919 * fsl_get_inb_message - Fetch inbound message from the MPC85xx message unit
886 * @mport: Master port implementing the inbound message unit 920 * @mport: Master port implementing the inbound message unit
887 * @mbox: Inbound mailbox number 921 * @mbox: Inbound mailbox number
888 * 922 *
889 * Gets the next available inbound message from the inbound message queue. 923 * Gets the next available inbound message from the inbound message queue.
890 * A pointer to the message is returned on success or NULL on failure. 924 * A pointer to the message is returned on success or NULL on failure.
891 */ 925 */
892void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox) 926static void *fsl_get_inb_message(struct rio_mport *mport, int mbox)
893{ 927{
894 struct rio_priv *priv = mport->priv; 928 struct rio_priv *priv = mport->priv;
895 u32 phys_buf, virt_buf; 929 u32 phys_buf, virt_buf;
@@ -926,8 +960,6 @@ void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
926 return buf; 960 return buf;
927} 961}
928 962
929EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
930
931/** 963/**
932 * fsl_rio_dbell_handler - MPC85xx doorbell interrupt handler 964 * fsl_rio_dbell_handler - MPC85xx doorbell interrupt handler
933 * @irq: Linux interrupt number 965 * @irq: Linux interrupt number
@@ -954,7 +986,6 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
954 if (dsr & DOORBELL_DSR_QFI) { 986 if (dsr & DOORBELL_DSR_QFI) {
955 pr_info("RIO: doorbell queue full\n"); 987 pr_info("RIO: doorbell queue full\n");
956 out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_QFI); 988 out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_QFI);
957 goto out;
958 } 989 }
959 990
960 /* XXX Need to check/dispatch until queue empty */ 991 /* XXX Need to check/dispatch until queue empty */
@@ -1051,6 +1082,40 @@ static int fsl_rio_doorbell_init(struct rio_mport *mport)
1051 return rc; 1082 return rc;
1052} 1083}
1053 1084
1085static void port_error_handler(struct rio_mport *port, int offset)
1086{
1087 /*XXX: Error recovery is not implemented, we just clear errors */
1088 out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0);
1089
1090 if (offset == 0) {
1091 out_be32((u32 *)(rio_regs_win + RIO_PORT1_EDCSR), 0);
1092 out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), 0);
1093 out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR);
1094 } else {
1095 out_be32((u32 *)(rio_regs_win + RIO_PORT2_EDCSR), 0);
1096 out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), 0);
1097 out_be32((u32 *)(rio_regs_win + RIO_PORT2_ESCSR), ESCSR_CLEAR);
1098 }
1099}
1100
1101static void msg_unit_error_handler(struct rio_mport *port)
1102{
1103 struct rio_priv *priv = port->priv;
1104
1105 /*XXX: Error recovery is not implemented, we just clear errors */
1106 out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0);
1107
1108 out_be32((u32 *)(rio_regs_win + RIO_IM0SR), IMSR_CLEAR);
1109 out_be32((u32 *)(rio_regs_win + RIO_IM1SR), IMSR_CLEAR);
1110 out_be32((u32 *)(rio_regs_win + RIO_OM0SR), OMSR_CLEAR);
1111 out_be32((u32 *)(rio_regs_win + RIO_OM1SR), OMSR_CLEAR);
1112
1113 out_be32(&priv->msg_regs->odsr, ODSR_CLEAR);
1114 out_be32(&priv->msg_regs->dsr, IDSR_CLEAR);
1115
1116 out_be32(&priv->msg_regs->pwsr, IPWSR_CLEAR);
1117}
1118
1054/** 1119/**
1055 * fsl_rio_port_write_handler - MPC85xx port write interrupt handler 1120 * fsl_rio_port_write_handler - MPC85xx port write interrupt handler
1056 * @irq: Linux interrupt number 1121 * @irq: Linux interrupt number
@@ -1067,18 +1132,12 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
1067 struct rio_priv *priv = port->priv; 1132 struct rio_priv *priv = port->priv;
1068 u32 epwisr, tmp; 1133 u32 epwisr, tmp;
1069 1134
1070 ipwmr = in_be32(&priv->msg_regs->pwmr);
1071 ipwsr = in_be32(&priv->msg_regs->pwsr);
1072
1073 epwisr = in_be32(priv->regs_win + RIO_EPWISR); 1135 epwisr = in_be32(priv->regs_win + RIO_EPWISR);
1074 if (epwisr & 0x80000000) { 1136 if (!(epwisr & RIO_EPWISR_PW))
1075 tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); 1137 goto pw_done;
1076 pr_info("RIO_LTLEDCSR = 0x%x\n", tmp);
1077 out_be32(priv->regs_win + RIO_LTLEDCSR, 0);
1078 }
1079 1138
1080 if (!(epwisr & 0x00000001)) 1139 ipwmr = in_be32(&priv->msg_regs->pwmr);
1081 return IRQ_HANDLED; 1140 ipwsr = in_be32(&priv->msg_regs->pwsr);
1082 1141
1083#ifdef DEBUG_PW 1142#ifdef DEBUG_PW
1084 pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr); 1143 pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr);
@@ -1094,20 +1153,6 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
1094 pr_debug(" PWB"); 1153 pr_debug(" PWB");
1095 pr_debug(" )\n"); 1154 pr_debug(" )\n");
1096#endif 1155#endif
1097 out_be32(&priv->msg_regs->pwsr,
1098 ipwsr & (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD));
1099
1100 if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
1101 priv->port_write_msg.err_count++;
1102 pr_info("RIO: Port-Write Transaction Err (%d)\n",
1103 priv->port_write_msg.err_count);
1104 }
1105 if (ipwsr & RIO_IPWSR_PWD) {
1106 priv->port_write_msg.discard_count++;
1107 pr_info("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
1108 priv->port_write_msg.discard_count);
1109 }
1110
1111 /* Schedule deferred processing if PW was received */ 1156 /* Schedule deferred processing if PW was received */
1112 if (ipwsr & RIO_IPWSR_QFI) { 1157 if (ipwsr & RIO_IPWSR_QFI) {
1113 /* Save PW message (if there is room in FIFO), 1158 /* Save PW message (if there is room in FIFO),
@@ -1119,16 +1164,55 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
1119 RIO_PW_MSG_SIZE); 1164 RIO_PW_MSG_SIZE);
1120 } else { 1165 } else {
1121 priv->port_write_msg.discard_count++; 1166 priv->port_write_msg.discard_count++;
1122 pr_info("RIO: ISR Discarded Port-Write Msg(s) (%d)\n", 1167 pr_debug("RIO: ISR Discarded Port-Write Msg(s) (%d)\n",
1123 priv->port_write_msg.discard_count); 1168 priv->port_write_msg.discard_count);
1124 } 1169 }
1170 /* Clear interrupt and issue Clear Queue command. This allows
1171 * another port-write to be received.
1172 */
1173 out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_QFI);
1174 out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ);
1175
1125 schedule_work(&priv->pw_work); 1176 schedule_work(&priv->pw_work);
1126 } 1177 }
1127 1178
1128 /* Issue Clear Queue command. This allows another 1179 if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
1129 * port-write to be received. 1180 priv->port_write_msg.err_count++;
1130 */ 1181 pr_debug("RIO: Port-Write Transaction Err (%d)\n",
1131 out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ); 1182 priv->port_write_msg.err_count);
1183 /* Clear Transaction Error: port-write controller should be
1184 * disabled when clearing this error
1185 */
1186 out_be32(&priv->msg_regs->pwmr, ipwmr & ~RIO_IPWMR_PWE);
1187 out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_TE);
1188 out_be32(&priv->msg_regs->pwmr, ipwmr);
1189 }
1190
1191 if (ipwsr & RIO_IPWSR_PWD) {
1192 priv->port_write_msg.discard_count++;
1193 pr_debug("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
1194 priv->port_write_msg.discard_count);
1195 out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_PWD);
1196 }
1197
1198pw_done:
1199 if (epwisr & RIO_EPWISR_PINT1) {
1200 tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
1201 pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
1202 port_error_handler(port, 0);
1203 }
1204
1205 if (epwisr & RIO_EPWISR_PINT2) {
1206 tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
1207 pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
1208 port_error_handler(port, 1);
1209 }
1210
1211 if (epwisr & RIO_EPWISR_MU) {
1212 tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
1213 pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
1214 msg_unit_error_handler(port);
1215 }
1132 1216
1133 return IRQ_HANDLED; 1217 return IRQ_HANDLED;
1134} 1218}
@@ -1238,12 +1322,14 @@ static int fsl_rio_port_write_init(struct rio_mport *mport)
1238 1322
1239 1323
1240 /* Hook up port-write handler */ 1324 /* Hook up port-write handler */
1241 rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler, 0, 1325 rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler,
1242 "port-write", (void *)mport); 1326 IRQF_SHARED, "port-write", (void *)mport);
1243 if (rc < 0) { 1327 if (rc < 0) {
1244 pr_err("MPC85xx RIO: unable to request inbound doorbell irq"); 1328 pr_err("MPC85xx RIO: unable to request inbound doorbell irq");
1245 goto err_out; 1329 goto err_out;
1246 } 1330 }
1331 /* Enable Error Interrupt */
1332 out_be32((u32 *)(rio_regs_win + RIO_LTLEECSR), LTLEECSR_ENABLE_ALL);
1247 1333
1248 INIT_WORK(&priv->pw_work, fsl_pw_dpc); 1334 INIT_WORK(&priv->pw_work, fsl_pw_dpc);
1249 spin_lock_init(&priv->pw_fifo_lock); 1335 spin_lock_init(&priv->pw_fifo_lock);
@@ -1268,28 +1354,6 @@ err_out:
1268 return rc; 1354 return rc;
1269} 1355}
1270 1356
1271static char *cmdline = NULL;
1272
1273static int fsl_rio_get_hdid(int index)
1274{
1275 /* XXX Need to parse multiple entries in some format */
1276 if (!cmdline)
1277 return -1;
1278
1279 return simple_strtol(cmdline, NULL, 0);
1280}
1281
1282static int fsl_rio_get_cmdline(char *s)
1283{
1284 if (!s)
1285 return 0;
1286
1287 cmdline = s;
1288 return 1;
1289}
1290
1291__setup("riohdid=", fsl_rio_get_cmdline);
1292
1293static inline void fsl_rio_info(struct device *dev, u32 ccsr) 1357static inline void fsl_rio_info(struct device *dev, u32 ccsr)
1294{ 1358{
1295 const char *str; 1359 const char *str;
@@ -1406,13 +1470,19 @@ int fsl_rio_setup(struct platform_device *dev)
1406 ops->cwrite = fsl_rio_config_write; 1470 ops->cwrite = fsl_rio_config_write;
1407 ops->dsend = fsl_rio_doorbell_send; 1471 ops->dsend = fsl_rio_doorbell_send;
1408 ops->pwenable = fsl_rio_pw_enable; 1472 ops->pwenable = fsl_rio_pw_enable;
1473 ops->open_outb_mbox = fsl_open_outb_mbox;
1474 ops->open_inb_mbox = fsl_open_inb_mbox;
1475 ops->close_outb_mbox = fsl_close_outb_mbox;
1476 ops->close_inb_mbox = fsl_close_inb_mbox;
1477 ops->add_outb_message = fsl_add_outb_message;
1478 ops->add_inb_buffer = fsl_add_inb_buffer;
1479 ops->get_inb_message = fsl_get_inb_message;
1409 1480
1410 port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); 1481 port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
1411 if (!port) { 1482 if (!port) {
1412 rc = -ENOMEM; 1483 rc = -ENOMEM;
1413 goto err_port; 1484 goto err_port;
1414 } 1485 }
1415 port->id = 0;
1416 port->index = 0; 1486 port->index = 0;
1417 1487
1418 priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL); 1488 priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL);
@@ -1428,6 +1498,14 @@ int fsl_rio_setup(struct platform_device *dev)
1428 port->iores.flags = IORESOURCE_MEM; 1498 port->iores.flags = IORESOURCE_MEM;
1429 port->iores.name = "rio_io_win"; 1499 port->iores.name = "rio_io_win";
1430 1500
1501 if (request_resource(&iomem_resource, &port->iores) < 0) {
1502 dev_err(&dev->dev, "RIO: Error requesting master port region"
1503 " 0x%016llx-0x%016llx\n",
1504 (u64)port->iores.start, (u64)port->iores.end);
1505 rc = -ENOMEM;
1506 goto err_res;
1507 }
1508
1431 priv->pwirq = irq_of_parse_and_map(dev->dev.of_node, 0); 1509 priv->pwirq = irq_of_parse_and_map(dev->dev.of_node, 0);
1432 priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2); 1510 priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2);
1433 priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3); 1511 priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3);
@@ -1443,10 +1521,8 @@ int fsl_rio_setup(struct platform_device *dev)
1443 priv->dev = &dev->dev; 1521 priv->dev = &dev->dev;
1444 1522
1445 port->ops = ops; 1523 port->ops = ops;
1446 port->host_deviceid = fsl_rio_get_hdid(port->id);
1447
1448 port->priv = priv; 1524 port->priv = priv;
1449 rio_register_mport(port); 1525 port->phys_efptr = 0x100;
1450 1526
1451 priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1); 1527 priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
1452 rio_regs_win = priv->regs_win; 1528 rio_regs_win = priv->regs_win;
@@ -1493,6 +1569,15 @@ int fsl_rio_setup(struct platform_device *dev)
1493 dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n", 1569 dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
1494 port->sys_size ? 65536 : 256); 1570 port->sys_size ? 65536 : 256);
1495 1571
1572 if (rio_register_mport(port))
1573 goto err;
1574
1575 if (port->host_deviceid >= 0)
1576 out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST |
1577 RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED);
1578 else
1579 out_be32(priv->regs_win + RIO_GCCSR, 0x00000000);
1580
1496 priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win 1581 priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
1497 + RIO_ATMU_REGS_OFFSET); 1582 + RIO_ATMU_REGS_OFFSET);
1498 priv->maint_atmu_regs = priv->atmu_regs + 1; 1583 priv->maint_atmu_regs = priv->atmu_regs + 1;
@@ -1519,16 +1604,10 @@ int fsl_rio_setup(struct platform_device *dev)
1519 fsl_rio_doorbell_init(port); 1604 fsl_rio_doorbell_init(port);
1520 fsl_rio_port_write_init(port); 1605 fsl_rio_port_write_init(port);
1521 1606
1522#ifdef CONFIG_E500
1523 saved_mcheck_exception = ppc_md.machine_check_exception;
1524 ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
1525#endif
1526 /* Ensure that RFXE is set */
1527 mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000));
1528
1529 return 0; 1607 return 0;
1530err: 1608err:
1531 iounmap(priv->regs_win); 1609 iounmap(priv->regs_win);
1610err_res:
1532 kfree(priv); 1611 kfree(priv);
1533err_priv: 1612err_priv:
1534 kfree(port); 1613 kfree(port);
@@ -1540,21 +1619,12 @@ err_ops:
1540 1619
1541/* The probe function for RapidIO peer-to-peer network. 1620/* The probe function for RapidIO peer-to-peer network.
1542 */ 1621 */
1543static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev, 1622static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev)
1544 const struct of_device_id *match)
1545{ 1623{
1546 int rc;
1547 printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n", 1624 printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n",
1548 dev->dev.of_node->full_name); 1625 dev->dev.of_node->full_name);
1549 1626
1550 rc = fsl_rio_setup(dev); 1627 return fsl_rio_setup(dev);
1551 if (rc)
1552 goto out;
1553
1554 /* Enumerate all registered ports */
1555 rc = rio_init_mports();
1556out:
1557 return rc;
1558}; 1628};
1559 1629
1560static const struct of_device_id fsl_of_rio_rpn_ids[] = { 1630static const struct of_device_id fsl_of_rio_rpn_ids[] = {
@@ -1564,7 +1634,7 @@ static const struct of_device_id fsl_of_rio_rpn_ids[] = {
1564 {}, 1634 {},
1565}; 1635};
1566 1636
1567static struct of_platform_driver fsl_of_rio_rpn_driver = { 1637static struct platform_driver fsl_of_rio_rpn_driver = {
1568 .driver = { 1638 .driver = {
1569 .name = "fsl-of-rio", 1639 .name = "fsl-of-rio",
1570 .owner = THIS_MODULE, 1640 .owner = THIS_MODULE,
@@ -1575,7 +1645,7 @@ static struct of_platform_driver fsl_of_rio_rpn_driver = {
1575 1645
1576static __init int fsl_of_rio_rpn_init(void) 1646static __init int fsl_of_rio_rpn_init(void)
1577{ 1647{
1578 return of_register_platform_driver(&fsl_of_rio_rpn_driver); 1648 return platform_driver_register(&fsl_of_rio_rpn_driver);
1579} 1649}
1580 1650
1581subsys_initcall(fsl_of_rio_rpn_init); 1651subsys_initcall(fsl_of_rio_rpn_init);