diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-12-29 03:45:15 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-12-29 03:45:15 -0500 |
| commit | e1df957670aef74ffd9a4ad93e6d2c90bf6b4845 (patch) | |
| tree | bca1fcfef55b3e3e82c9a822b4ac6428fce2b419 /arch/powerpc/sysdev | |
| parent | 2b583d8bc8d7105b58d7481a4a0ceb718dac49c6 (diff) | |
| parent | 3c92ec8ae91ecf59d88c798301833d7cf83f2179 (diff) | |
Merge branch 'linus' into perfcounters/core
Conflicts:
fs/exec.c
include/linux/init_task.h
Simple context conflicts.
Diffstat (limited to 'arch/powerpc/sysdev')
| -rw-r--r-- | arch/powerpc/sysdev/bestcomm/ata.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/bestcomm/ata.h | 19 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/bestcomm/bestcomm.c | 7 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/bestcomm/bestcomm.h | 61 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/bestcomm/bestcomm_priv.h | 20 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/dcr-low.S | 8 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/dcr.c | 5 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/fsl_soc.c | 241 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/grackle.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/mpic.c | 32 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/ppc4xx_pci.c | 306 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/ucc.c | 4 |
14 files changed, 328 insertions, 387 deletions
diff --git a/arch/powerpc/sysdev/bestcomm/ata.c b/arch/powerpc/sysdev/bestcomm/ata.c index 1f5258fb38c3..901c9f91e5dd 100644 --- a/arch/powerpc/sysdev/bestcomm/ata.c +++ b/arch/powerpc/sysdev/bestcomm/ata.c | |||
| @@ -61,6 +61,9 @@ bcom_ata_init(int queue_len, int maxbufsize) | |||
| 61 | struct bcom_ata_var *var; | 61 | struct bcom_ata_var *var; |
| 62 | struct bcom_ata_inc *inc; | 62 | struct bcom_ata_inc *inc; |
| 63 | 63 | ||
| 64 | /* Prefetch breaks ATA DMA. Turn it off for ATA DMA */ | ||
| 65 | bcom_disable_prefetch(); | ||
| 66 | |||
| 64 | tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0); | 67 | tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0); |
| 65 | if (!tsk) | 68 | if (!tsk) |
| 66 | return NULL; | 69 | return NULL; |
diff --git a/arch/powerpc/sysdev/bestcomm/ata.h b/arch/powerpc/sysdev/bestcomm/ata.h index 10982769c465..0b2371811334 100644 --- a/arch/powerpc/sysdev/bestcomm/ata.h +++ b/arch/powerpc/sysdev/bestcomm/ata.h | |||
| @@ -16,22 +16,15 @@ | |||
| 16 | 16 | ||
| 17 | struct bcom_ata_bd { | 17 | struct bcom_ata_bd { |
| 18 | u32 status; | 18 | u32 status; |
| 19 | u32 dst_pa; | ||
| 20 | u32 src_pa; | 19 | u32 src_pa; |
| 20 | u32 dst_pa; | ||
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | extern struct bcom_task * | 23 | extern struct bcom_task * bcom_ata_init(int queue_len, int maxbufsize); |
| 24 | bcom_ata_init(int queue_len, int maxbufsize); | 24 | extern void bcom_ata_rx_prepare(struct bcom_task *tsk); |
| 25 | 25 | extern void bcom_ata_tx_prepare(struct bcom_task *tsk); | |
| 26 | extern void | 26 | extern void bcom_ata_reset_bd(struct bcom_task *tsk); |
| 27 | bcom_ata_rx_prepare(struct bcom_task *tsk); | 27 | extern void bcom_ata_release(struct bcom_task *tsk); |
| 28 | |||
| 29 | extern void | ||
| 30 | bcom_ata_tx_prepare(struct bcom_task *tsk); | ||
| 31 | |||
| 32 | extern void | ||
| 33 | bcom_ata_reset_bd(struct bcom_task *tsk); | ||
| 34 | |||
| 35 | 28 | ||
| 36 | #endif /* __BESTCOMM_ATA_H__ */ | 29 | #endif /* __BESTCOMM_ATA_H__ */ |
| 37 | 30 | ||
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index 446c9ea85b30..378ebd9aac18 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c | |||
| @@ -279,7 +279,6 @@ bcom_engine_init(void) | |||
| 279 | int task; | 279 | int task; |
| 280 | phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa; | 280 | phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa; |
| 281 | unsigned int tdt_size, ctx_size, var_size, fdt_size; | 281 | unsigned int tdt_size, ctx_size, var_size, fdt_size; |
| 282 | u16 regval; | ||
| 283 | 282 | ||
| 284 | /* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */ | 283 | /* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */ |
| 285 | tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt); | 284 | tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt); |
| @@ -331,10 +330,8 @@ bcom_engine_init(void) | |||
| 331 | out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS); | 330 | out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS); |
| 332 | 331 | ||
| 333 | /* Disable COMM Bus Prefetch on the original 5200; it's broken */ | 332 | /* Disable COMM Bus Prefetch on the original 5200; it's broken */ |
| 334 | if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) { | 333 | if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) |
| 335 | regval = in_be16(&bcom_eng->regs->PtdCntrl); | 334 | bcom_disable_prefetch(); |
| 336 | out_be16(&bcom_eng->regs->PtdCntrl, regval | 1); | ||
| 337 | } | ||
| 338 | 335 | ||
| 339 | /* Init lock */ | 336 | /* Init lock */ |
| 340 | spin_lock_init(&bcom_eng->lock); | 337 | spin_lock_init(&bcom_eng->lock); |
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.h b/arch/powerpc/sysdev/bestcomm/bestcomm.h index c960a8b49655..23a95f80dfdb 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.h +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.h | |||
| @@ -16,8 +16,19 @@ | |||
| 16 | #ifndef __BESTCOMM_H__ | 16 | #ifndef __BESTCOMM_H__ |
| 17 | #define __BESTCOMM_H__ | 17 | #define __BESTCOMM_H__ |
| 18 | 18 | ||
| 19 | struct bcom_bd; /* defined later on ... */ | 19 | /** |
| 20 | 20 | * struct bcom_bd - Structure describing a generic BestComm buffer descriptor | |
| 21 | * @status: The current status of this buffer. Exact meaning depends on the | ||
| 22 | * task type | ||
| 23 | * @data: An array of u32 extra data. Size of array is task dependant. | ||
| 24 | * | ||
| 25 | * Note: Don't dereference a bcom_bd pointer as an array. The size of the | ||
| 26 | * bcom_bd is variable. Use bcom_get_bd() instead. | ||
| 27 | */ | ||
| 28 | struct bcom_bd { | ||
| 29 | u32 status; | ||
| 30 | u32 data[0]; /* variable payload size */ | ||
| 31 | }; | ||
| 21 | 32 | ||
| 22 | /* ======================================================================== */ | 33 | /* ======================================================================== */ |
| 23 | /* Generic task management */ | 34 | /* Generic task management */ |
| @@ -84,17 +95,6 @@ bcom_get_task_irq(struct bcom_task *tsk) { | |||
| 84 | /* BD based tasks helpers */ | 95 | /* BD based tasks helpers */ |
| 85 | /* ======================================================================== */ | 96 | /* ======================================================================== */ |
| 86 | 97 | ||
| 87 | /** | ||
| 88 | * struct bcom_bd - Structure describing a generic BestComm buffer descriptor | ||
| 89 | * @status: The current status of this buffer. Exact meaning depends on the | ||
| 90 | * task type | ||
| 91 | * @data: An array of u32 whose meaning depends on the task type. | ||
| 92 | */ | ||
| 93 | struct bcom_bd { | ||
| 94 | u32 status; | ||
| 95 | u32 data[1]; /* variable, but at least 1 */ | ||
| 96 | }; | ||
| 97 | |||
| 98 | #define BCOM_BD_READY 0x40000000ul | 98 | #define BCOM_BD_READY 0x40000000ul |
| 99 | 99 | ||
| 100 | /** _bcom_next_index - Get next input index. | 100 | /** _bcom_next_index - Get next input index. |
| @@ -140,15 +140,31 @@ bcom_queue_full(struct bcom_task *tsk) | |||
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | /** | 142 | /** |
| 143 | * bcom_get_bd - Get a BD from the queue | ||
| 144 | * @tsk: The BestComm task structure | ||
| 145 | * index: Index of the BD to fetch | ||
| 146 | */ | ||
| 147 | static inline struct bcom_bd | ||
| 148 | *bcom_get_bd(struct bcom_task *tsk, unsigned int index) | ||
| 149 | { | ||
| 150 | /* A cast to (void*) so the address can be incremented by the | ||
| 151 | * real size instead of by sizeof(struct bcom_bd) */ | ||
| 152 | return ((void *)tsk->bd) + (index * tsk->bd_size); | ||
| 153 | } | ||
| 154 | |||
| 155 | /** | ||
| 143 | * bcom_buffer_done - Checks if a BestComm | 156 | * bcom_buffer_done - Checks if a BestComm |
| 144 | * @tsk: The BestComm task structure | 157 | * @tsk: The BestComm task structure |
| 145 | */ | 158 | */ |
| 146 | static inline int | 159 | static inline int |
| 147 | bcom_buffer_done(struct bcom_task *tsk) | 160 | bcom_buffer_done(struct bcom_task *tsk) |
| 148 | { | 161 | { |
| 162 | struct bcom_bd *bd; | ||
| 149 | if (bcom_queue_empty(tsk)) | 163 | if (bcom_queue_empty(tsk)) |
| 150 | return 0; | 164 | return 0; |
| 151 | return !(tsk->bd[tsk->outdex].status & BCOM_BD_READY); | 165 | |
| 166 | bd = bcom_get_bd(tsk, tsk->outdex); | ||
| 167 | return !(bd->status & BCOM_BD_READY); | ||
| 152 | } | 168 | } |
| 153 | 169 | ||
| 154 | /** | 170 | /** |
| @@ -160,16 +176,21 @@ bcom_buffer_done(struct bcom_task *tsk) | |||
| 160 | static inline struct bcom_bd * | 176 | static inline struct bcom_bd * |
| 161 | bcom_prepare_next_buffer(struct bcom_task *tsk) | 177 | bcom_prepare_next_buffer(struct bcom_task *tsk) |
| 162 | { | 178 | { |
| 163 | tsk->bd[tsk->index].status = 0; /* cleanup last status */ | 179 | struct bcom_bd *bd; |
| 164 | return &tsk->bd[tsk->index]; | 180 | |
| 181 | bd = bcom_get_bd(tsk, tsk->index); | ||
| 182 | bd->status = 0; /* cleanup last status */ | ||
| 183 | return bd; | ||
| 165 | } | 184 | } |
| 166 | 185 | ||
| 167 | static inline void | 186 | static inline void |
| 168 | bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie) | 187 | bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie) |
| 169 | { | 188 | { |
| 189 | struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index); | ||
| 190 | |||
| 170 | tsk->cookie[tsk->index] = cookie; | 191 | tsk->cookie[tsk->index] = cookie; |
| 171 | mb(); /* ensure the bd is really up-to-date */ | 192 | mb(); /* ensure the bd is really up-to-date */ |
| 172 | tsk->bd[tsk->index].status |= BCOM_BD_READY; | 193 | bd->status |= BCOM_BD_READY; |
| 173 | tsk->index = _bcom_next_index(tsk); | 194 | tsk->index = _bcom_next_index(tsk); |
| 174 | if (tsk->flags & BCOM_FLAGS_ENABLE_TASK) | 195 | if (tsk->flags & BCOM_FLAGS_ENABLE_TASK) |
| 175 | bcom_enable(tsk); | 196 | bcom_enable(tsk); |
| @@ -179,10 +200,12 @@ static inline void * | |||
| 179 | bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd) | 200 | bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd) |
| 180 | { | 201 | { |
| 181 | void *cookie = tsk->cookie[tsk->outdex]; | 202 | void *cookie = tsk->cookie[tsk->outdex]; |
| 203 | struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex); | ||
| 204 | |||
| 182 | if (p_status) | 205 | if (p_status) |
| 183 | *p_status = tsk->bd[tsk->outdex].status; | 206 | *p_status = bd->status; |
| 184 | if (p_bd) | 207 | if (p_bd) |
| 185 | *p_bd = &tsk->bd[tsk->outdex]; | 208 | *p_bd = bd; |
| 186 | tsk->outdex = _bcom_next_outdex(tsk); | 209 | tsk->outdex = _bcom_next_outdex(tsk); |
| 187 | return cookie; | 210 | return cookie; |
| 188 | } | 211 | } |
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h index 866a2915ef2f..eb0d1c883c31 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h +++ b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h | |||
| @@ -198,8 +198,8 @@ struct bcom_task_header { | |||
| 198 | #define BCOM_IPR_SCTMR_1 2 | 198 | #define BCOM_IPR_SCTMR_1 2 |
| 199 | #define BCOM_IPR_FEC_RX 6 | 199 | #define BCOM_IPR_FEC_RX 6 |
| 200 | #define BCOM_IPR_FEC_TX 5 | 200 | #define BCOM_IPR_FEC_TX 5 |
| 201 | #define BCOM_IPR_ATA_RX 4 | 201 | #define BCOM_IPR_ATA_RX 7 |
| 202 | #define BCOM_IPR_ATA_TX 3 | 202 | #define BCOM_IPR_ATA_TX 7 |
| 203 | #define BCOM_IPR_SCPCI_RX 2 | 203 | #define BCOM_IPR_SCPCI_RX 2 |
| 204 | #define BCOM_IPR_SCPCI_TX 2 | 204 | #define BCOM_IPR_SCPCI_TX 2 |
| 205 | #define BCOM_IPR_PSC3_RX 2 | 205 | #define BCOM_IPR_PSC3_RX 2 |
| @@ -241,6 +241,22 @@ extern void bcom_set_initiator(int task, int initiator); | |||
| 241 | 241 | ||
| 242 | #define TASK_ENABLE 0x8000 | 242 | #define TASK_ENABLE 0x8000 |
| 243 | 243 | ||
| 244 | /** | ||
| 245 | * bcom_disable_prefetch - Hook to disable bus prefetching | ||
| 246 | * | ||
| 247 | * ATA DMA and the original MPC5200 need this due to silicon bugs. At the | ||
| 248 | * moment disabling prefetch is a one-way street. There is no mechanism | ||
| 249 | * in place to turn prefetch back on after it has been disabled. There is | ||
| 250 | * no reason it couldn't be done, it would just be more complex to implement. | ||
| 251 | */ | ||
| 252 | static inline void bcom_disable_prefetch(void) | ||
| 253 | { | ||
| 254 | u16 regval; | ||
| 255 | |||
| 256 | regval = in_be16(&bcom_eng->regs->PtdCntrl); | ||
| 257 | out_be16(&bcom_eng->regs->PtdCntrl, regval | 1); | ||
| 258 | }; | ||
| 259 | |||
| 244 | static inline void | 260 | static inline void |
| 245 | bcom_enable_task(int task) | 261 | bcom_enable_task(int task) |
| 246 | { | 262 | { |
diff --git a/arch/powerpc/sysdev/dcr-low.S b/arch/powerpc/sysdev/dcr-low.S index 2078f39e2f17..d3098ef1404a 100644 --- a/arch/powerpc/sysdev/dcr-low.S +++ b/arch/powerpc/sysdev/dcr-low.S | |||
| @@ -11,14 +11,20 @@ | |||
| 11 | 11 | ||
| 12 | #include <asm/ppc_asm.h> | 12 | #include <asm/ppc_asm.h> |
| 13 | #include <asm/processor.h> | 13 | #include <asm/processor.h> |
| 14 | #include <asm/bug.h> | ||
| 14 | 15 | ||
| 15 | #define DCR_ACCESS_PROLOG(table) \ | 16 | #define DCR_ACCESS_PROLOG(table) \ |
| 17 | cmpli cr0,r3,1024; \ | ||
| 16 | rlwinm r3,r3,4,18,27; \ | 18 | rlwinm r3,r3,4,18,27; \ |
| 17 | lis r5,table@h; \ | 19 | lis r5,table@h; \ |
| 18 | ori r5,r5,table@l; \ | 20 | ori r5,r5,table@l; \ |
| 19 | add r3,r3,r5; \ | 21 | add r3,r3,r5; \ |
| 22 | bge- 1f; \ | ||
| 20 | mtctr r3; \ | 23 | mtctr r3; \ |
| 21 | bctr | 24 | bctr; \ |
| 25 | 1: trap; \ | ||
| 26 | EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0; \ | ||
| 27 | blr | ||
| 22 | 28 | ||
| 23 | _GLOBAL(__mfdcr) | 29 | _GLOBAL(__mfdcr) |
| 24 | DCR_ACCESS_PROLOG(__mfdcr_table) | 30 | DCR_ACCESS_PROLOG(__mfdcr_table) |
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index a8ba9983dd5a..bb44aa9fd470 100644 --- a/arch/powerpc/sysdev/dcr.c +++ b/arch/powerpc/sysdev/dcr.c | |||
| @@ -124,7 +124,8 @@ EXPORT_SYMBOL_GPL(dcr_write_generic); | |||
| 124 | 124 | ||
| 125 | #endif /* defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) */ | 125 | #endif /* defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) */ |
| 126 | 126 | ||
| 127 | unsigned int dcr_resource_start(struct device_node *np, unsigned int index) | 127 | unsigned int dcr_resource_start(const struct device_node *np, |
| 128 | unsigned int index) | ||
| 128 | { | 129 | { |
| 129 | unsigned int ds; | 130 | unsigned int ds; |
| 130 | const u32 *dr = of_get_property(np, "dcr-reg", &ds); | 131 | const u32 *dr = of_get_property(np, "dcr-reg", &ds); |
| @@ -136,7 +137,7 @@ unsigned int dcr_resource_start(struct device_node *np, unsigned int index) | |||
| 136 | } | 137 | } |
| 137 | EXPORT_SYMBOL_GPL(dcr_resource_start); | 138 | EXPORT_SYMBOL_GPL(dcr_resource_start); |
| 138 | 139 | ||
| 139 | unsigned int dcr_resource_len(struct device_node *np, unsigned int index) | 140 | unsigned int dcr_resource_len(const struct device_node *np, unsigned int index) |
| 140 | { | 141 | { |
| 141 | unsigned int ds; | 142 | unsigned int ds; |
| 142 | const u32 *dr = of_get_property(np, "dcr-reg", &ds); | 143 | const u32 *dr = of_get_property(np, "dcr-reg", &ds); |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 5b264eb4b1f7..d5f9ae0f1b75 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
| @@ -187,7 +187,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary) | |||
| 187 | printk(KERN_WARNING "Can't get bus-range for %s, assume" | 187 | printk(KERN_WARNING "Can't get bus-range for %s, assume" |
| 188 | " bus 0\n", dev->full_name); | 188 | " bus 0\n", dev->full_name); |
| 189 | 189 | ||
| 190 | ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; | 190 | ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS); |
| 191 | hose = pcibios_alloc_controller(dev); | 191 | hose = pcibios_alloc_controller(dev); |
| 192 | if (!hose) | 192 | if (!hose) |
| 193 | return -ENOMEM; | 193 | return -ENOMEM; |
| @@ -300,7 +300,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev) | |||
| 300 | " bus 0\n", dev->full_name); | 300 | " bus 0\n", dev->full_name); |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; | 303 | ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS); |
| 304 | hose = pcibios_alloc_controller(dev); | 304 | hose = pcibios_alloc_controller(dev); |
| 305 | if (!hose) | 305 | if (!hose) |
| 306 | return -ENOMEM; | 306 | return -ENOMEM; |
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 26ecb96f9731..115cb16351fd 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c | |||
| @@ -207,236 +207,51 @@ static int __init of_add_fixed_phys(void) | |||
| 207 | arch_initcall(of_add_fixed_phys); | 207 | arch_initcall(of_add_fixed_phys); |
| 208 | #endif /* CONFIG_FIXED_PHY */ | 208 | #endif /* CONFIG_FIXED_PHY */ |
| 209 | 209 | ||
| 210 | static int gfar_mdio_of_init_one(struct device_node *np) | 210 | #ifdef CONFIG_PPC_83xx |
| 211 | { | 211 | static int __init mpc83xx_wdt_init(void) |
| 212 | int k; | ||
| 213 | struct device_node *child = NULL; | ||
| 214 | struct gianfar_mdio_data mdio_data; | ||
| 215 | struct platform_device *mdio_dev; | ||
| 216 | struct resource res; | ||
| 217 | int ret; | ||
| 218 | |||
| 219 | memset(&res, 0, sizeof(res)); | ||
| 220 | memset(&mdio_data, 0, sizeof(mdio_data)); | ||
| 221 | |||
| 222 | ret = of_address_to_resource(np, 0, &res); | ||
| 223 | if (ret) | ||
| 224 | return ret; | ||
| 225 | |||
| 226 | /* The gianfar device will try to use the same ID created below to find | ||
| 227 | * this bus, to coordinate register access (since they share). */ | ||
| 228 | mdio_dev = platform_device_register_simple("fsl-gianfar_mdio", | ||
| 229 | res.start&0xfffff, &res, 1); | ||
| 230 | if (IS_ERR(mdio_dev)) | ||
| 231 | return PTR_ERR(mdio_dev); | ||
| 232 | |||
| 233 | for (k = 0; k < 32; k++) | ||
| 234 | mdio_data.irq[k] = PHY_POLL; | ||
| 235 | |||
| 236 | while ((child = of_get_next_child(np, child)) != NULL) { | ||
| 237 | int irq = irq_of_parse_and_map(child, 0); | ||
| 238 | if (irq != NO_IRQ) { | ||
| 239 | const u32 *id = of_get_property(child, "reg", NULL); | ||
| 240 | mdio_data.irq[*id] = irq; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | ret = platform_device_add_data(mdio_dev, &mdio_data, | ||
| 245 | sizeof(struct gianfar_mdio_data)); | ||
| 246 | if (ret) | ||
| 247 | platform_device_unregister(mdio_dev); | ||
| 248 | |||
| 249 | return ret; | ||
| 250 | } | ||
| 251 | |||
| 252 | static int __init gfar_mdio_of_init(void) | ||
| 253 | { | ||
| 254 | struct device_node *np = NULL; | ||
| 255 | |||
| 256 | for_each_compatible_node(np, NULL, "fsl,gianfar-mdio") | ||
| 257 | gfar_mdio_of_init_one(np); | ||
| 258 | |||
| 259 | /* try the deprecated version */ | ||
| 260 | for_each_compatible_node(np, "mdio", "gianfar"); | ||
| 261 | gfar_mdio_of_init_one(np); | ||
| 262 | |||
| 263 | return 0; | ||
| 264 | } | ||
| 265 | |||
| 266 | arch_initcall(gfar_mdio_of_init); | ||
| 267 | |||
| 268 | static const char *gfar_tx_intr = "tx"; | ||
| 269 | static const char *gfar_rx_intr = "rx"; | ||
| 270 | static const char *gfar_err_intr = "error"; | ||
| 271 | |||
| 272 | static int __init gfar_of_init(void) | ||
| 273 | { | 212 | { |
| 213 | struct resource r; | ||
| 274 | struct device_node *np; | 214 | struct device_node *np; |
| 275 | unsigned int i; | 215 | struct platform_device *dev; |
| 276 | struct platform_device *gfar_dev; | 216 | u32 freq = fsl_get_sys_freq(); |
| 277 | struct resource res; | ||
| 278 | int ret; | 217 | int ret; |
| 279 | 218 | ||
| 280 | for (np = NULL, i = 0; | 219 | np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt"); |
| 281 | (np = of_find_compatible_node(np, "network", "gianfar")) != NULL; | ||
| 282 | i++) { | ||
| 283 | struct resource r[4]; | ||
| 284 | struct device_node *phy, *mdio; | ||
| 285 | struct gianfar_platform_data gfar_data; | ||
| 286 | const unsigned int *id; | ||
| 287 | const char *model; | ||
| 288 | const char *ctype; | ||
| 289 | const void *mac_addr; | ||
| 290 | const phandle *ph; | ||
| 291 | int n_res = 2; | ||
| 292 | |||
| 293 | if (!of_device_is_available(np)) | ||
| 294 | continue; | ||
| 295 | |||
| 296 | memset(r, 0, sizeof(r)); | ||
| 297 | memset(&gfar_data, 0, sizeof(gfar_data)); | ||
| 298 | |||
| 299 | ret = of_address_to_resource(np, 0, &r[0]); | ||
| 300 | if (ret) | ||
| 301 | goto err; | ||
| 302 | |||
| 303 | of_irq_to_resource(np, 0, &r[1]); | ||
| 304 | |||
| 305 | model = of_get_property(np, "model", NULL); | ||
| 306 | |||
| 307 | /* If we aren't the FEC we have multiple interrupts */ | ||
| 308 | if (model && strcasecmp(model, "FEC")) { | ||
| 309 | r[1].name = gfar_tx_intr; | ||
| 310 | |||
| 311 | r[2].name = gfar_rx_intr; | ||
| 312 | of_irq_to_resource(np, 1, &r[2]); | ||
| 313 | 220 | ||
| 314 | r[3].name = gfar_err_intr; | 221 | if (!np) { |
| 315 | of_irq_to_resource(np, 2, &r[3]); | 222 | ret = -ENODEV; |
| 316 | 223 | goto nodev; | |
| 317 | n_res += 2; | 224 | } |
| 318 | } | ||
| 319 | |||
| 320 | gfar_dev = | ||
| 321 | platform_device_register_simple("fsl-gianfar", i, &r[0], | ||
| 322 | n_res); | ||
| 323 | |||
| 324 | if (IS_ERR(gfar_dev)) { | ||
| 325 | ret = PTR_ERR(gfar_dev); | ||
| 326 | goto err; | ||
| 327 | } | ||
| 328 | |||
| 329 | mac_addr = of_get_mac_address(np); | ||
| 330 | if (mac_addr) | ||
| 331 | memcpy(gfar_data.mac_addr, mac_addr, 6); | ||
| 332 | |||
| 333 | if (model && !strcasecmp(model, "TSEC")) | ||
| 334 | gfar_data.device_flags = | ||
| 335 | FSL_GIANFAR_DEV_HAS_GIGABIT | | ||
| 336 | FSL_GIANFAR_DEV_HAS_COALESCE | | ||
| 337 | FSL_GIANFAR_DEV_HAS_RMON | | ||
| 338 | FSL_GIANFAR_DEV_HAS_MULTI_INTR; | ||
| 339 | if (model && !strcasecmp(model, "eTSEC")) | ||
| 340 | gfar_data.device_flags = | ||
| 341 | FSL_GIANFAR_DEV_HAS_GIGABIT | | ||
| 342 | FSL_GIANFAR_DEV_HAS_COALESCE | | ||
| 343 | FSL_GIANFAR_DEV_HAS_RMON | | ||
| 344 | FSL_GIANFAR_DEV_HAS_MULTI_INTR | | ||
| 345 | FSL_GIANFAR_DEV_HAS_CSUM | | ||
| 346 | FSL_GIANFAR_DEV_HAS_VLAN | | ||
| 347 | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; | ||
| 348 | |||
| 349 | ctype = of_get_property(np, "phy-connection-type", NULL); | ||
| 350 | |||
| 351 | /* We only care about rgmii-id. The rest are autodetected */ | ||
| 352 | if (ctype && !strcmp(ctype, "rgmii-id")) | ||
| 353 | gfar_data.interface = PHY_INTERFACE_MODE_RGMII_ID; | ||
| 354 | else | ||
| 355 | gfar_data.interface = PHY_INTERFACE_MODE_MII; | ||
| 356 | |||
| 357 | if (of_get_property(np, "fsl,magic-packet", NULL)) | ||
| 358 | gfar_data.device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; | ||
| 359 | |||
| 360 | ph = of_get_property(np, "phy-handle", NULL); | ||
| 361 | if (ph == NULL) { | ||
| 362 | u32 *fixed_link; | ||
| 363 | |||
| 364 | fixed_link = (u32 *)of_get_property(np, "fixed-link", | ||
| 365 | NULL); | ||
| 366 | if (!fixed_link) { | ||
| 367 | ret = -ENODEV; | ||
| 368 | goto unreg; | ||
| 369 | } | ||
| 370 | |||
| 371 | snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "0"); | ||
| 372 | gfar_data.phy_id = fixed_link[0]; | ||
| 373 | } else { | ||
| 374 | phy = of_find_node_by_phandle(*ph); | ||
| 375 | |||
| 376 | if (phy == NULL) { | ||
| 377 | ret = -ENODEV; | ||
| 378 | goto unreg; | ||
| 379 | } | ||
| 380 | |||
| 381 | mdio = of_get_parent(phy); | ||
| 382 | |||
| 383 | id = of_get_property(phy, "reg", NULL); | ||
| 384 | ret = of_address_to_resource(mdio, 0, &res); | ||
| 385 | if (ret) { | ||
| 386 | of_node_put(phy); | ||
| 387 | of_node_put(mdio); | ||
| 388 | goto unreg; | ||
| 389 | } | ||
| 390 | |||
| 391 | gfar_data.phy_id = *id; | ||
| 392 | snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx", | ||
| 393 | (unsigned long long)res.start&0xfffff); | ||
| 394 | 225 | ||
| 395 | of_node_put(phy); | 226 | memset(&r, 0, sizeof(r)); |
| 396 | of_node_put(mdio); | ||
| 397 | } | ||
| 398 | 227 | ||
| 399 | /* Get MDIO bus controlled by this eTSEC, if any. Normally only | 228 | ret = of_address_to_resource(np, 0, &r); |
| 400 | * eTSEC 1 will control an MDIO bus, not necessarily the same | 229 | if (ret) |
| 401 | * bus that its PHY is on ('mdio' above), so we can't just use | 230 | goto err; |
| 402 | * that. What we do is look for a gianfar mdio device that has | ||
| 403 | * overlapping registers with this device. That's really the | ||
| 404 | * whole point, to find the device sharing our registers to | ||
| 405 | * coordinate access with it. | ||
| 406 | */ | ||
| 407 | for_each_compatible_node(mdio, NULL, "fsl,gianfar-mdio") { | ||
| 408 | if (of_address_to_resource(mdio, 0, &res)) | ||
| 409 | continue; | ||
| 410 | |||
| 411 | if (res.start >= r[0].start && res.end <= r[0].end) { | ||
| 412 | /* Get the ID the mdio bus platform device was | ||
| 413 | * registered with. gfar_data.bus_id is | ||
| 414 | * different because it's for finding a PHY, | ||
| 415 | * while this is for finding a MII bus. | ||
| 416 | */ | ||
| 417 | gfar_data.mdio_bus = res.start&0xfffff; | ||
| 418 | of_node_put(mdio); | ||
| 419 | break; | ||
| 420 | } | ||
| 421 | } | ||
| 422 | 231 | ||
| 423 | ret = | 232 | dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1); |
| 424 | platform_device_add_data(gfar_dev, &gfar_data, | 233 | if (IS_ERR(dev)) { |
| 425 | sizeof(struct | 234 | ret = PTR_ERR(dev); |
| 426 | gianfar_platform_data)); | 235 | goto err; |
| 427 | if (ret) | ||
| 428 | goto unreg; | ||
| 429 | } | 236 | } |
| 430 | 237 | ||
| 238 | ret = platform_device_add_data(dev, &freq, sizeof(freq)); | ||
| 239 | if (ret) | ||
| 240 | goto unreg; | ||
| 241 | |||
| 242 | of_node_put(np); | ||
| 431 | return 0; | 243 | return 0; |
| 432 | 244 | ||
| 433 | unreg: | 245 | unreg: |
| 434 | platform_device_unregister(gfar_dev); | 246 | platform_device_unregister(dev); |
| 435 | err: | 247 | err: |
| 248 | of_node_put(np); | ||
| 249 | nodev: | ||
| 436 | return ret; | 250 | return ret; |
| 437 | } | 251 | } |
| 438 | 252 | ||
| 439 | arch_initcall(gfar_of_init); | 253 | arch_initcall(mpc83xx_wdt_init); |
| 254 | #endif | ||
| 440 | 255 | ||
| 441 | static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type) | 256 | static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type) |
| 442 | { | 257 | { |
diff --git a/arch/powerpc/sysdev/grackle.c b/arch/powerpc/sysdev/grackle.c index d502927644c6..5da37c2f22ee 100644 --- a/arch/powerpc/sysdev/grackle.c +++ b/arch/powerpc/sysdev/grackle.c | |||
| @@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_controller *hose) | |||
| 57 | { | 57 | { |
| 58 | setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0); | 58 | setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0); |
| 59 | if (machine_is_compatible("PowerMac1,1")) | 59 | if (machine_is_compatible("PowerMac1,1")) |
| 60 | ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; | 60 | ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS); |
| 61 | if (machine_is_compatible("AAPL,PowerBook1998")) | 61 | if (machine_is_compatible("AAPL,PowerBook1998")) |
| 62 | grackle_set_loop_snoop(hose, 1); | 62 | grackle_set_loop_snoop(hose, 1); |
| 63 | #if 0 /* Disabled for now, HW problems ??? */ | 63 | #if 0 /* Disabled for now, HW problems ??? */ |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 1890fb085cde..c82babb70074 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
| @@ -661,17 +661,6 @@ static inline void mpic_eoi(struct mpic *mpic) | |||
| 661 | (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI)); | 661 | (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI)); |
| 662 | } | 662 | } |
| 663 | 663 | ||
| 664 | #ifdef CONFIG_SMP | ||
| 665 | static irqreturn_t mpic_ipi_action(int irq, void *data) | ||
| 666 | { | ||
| 667 | long ipi = (long)data; | ||
| 668 | |||
| 669 | smp_message_recv(ipi); | ||
| 670 | |||
| 671 | return IRQ_HANDLED; | ||
| 672 | } | ||
| 673 | #endif /* CONFIG_SMP */ | ||
| 674 | |||
| 675 | /* | 664 | /* |
| 676 | * Linux descriptor level callbacks | 665 | * Linux descriptor level callbacks |
| 677 | */ | 666 | */ |
| @@ -1548,13 +1537,7 @@ unsigned int mpic_get_mcirq(void) | |||
| 1548 | void mpic_request_ipis(void) | 1537 | void mpic_request_ipis(void) |
| 1549 | { | 1538 | { |
| 1550 | struct mpic *mpic = mpic_primary; | 1539 | struct mpic *mpic = mpic_primary; |
| 1551 | long i, err; | 1540 | int i; |
| 1552 | static char *ipi_names[] = { | ||
| 1553 | "IPI0 (call function)", | ||
| 1554 | "IPI1 (reschedule)", | ||
| 1555 | "IPI2 (call function single)", | ||
| 1556 | "IPI3 (debugger break)", | ||
| 1557 | }; | ||
| 1558 | BUG_ON(mpic == NULL); | 1541 | BUG_ON(mpic == NULL); |
| 1559 | 1542 | ||
| 1560 | printk(KERN_INFO "mpic: requesting IPIs ... \n"); | 1543 | printk(KERN_INFO "mpic: requesting IPIs ... \n"); |
| @@ -1563,17 +1546,10 @@ void mpic_request_ipis(void) | |||
| 1563 | unsigned int vipi = irq_create_mapping(mpic->irqhost, | 1546 | unsigned int vipi = irq_create_mapping(mpic->irqhost, |
| 1564 | mpic->ipi_vecs[0] + i); | 1547 | mpic->ipi_vecs[0] + i); |
| 1565 | if (vipi == NO_IRQ) { | 1548 | if (vipi == NO_IRQ) { |
| 1566 | printk(KERN_ERR "Failed to map IPI %ld\n", i); | 1549 | printk(KERN_ERR "Failed to map %s\n", smp_ipi_name[i]); |
| 1567 | break; | 1550 | continue; |
| 1568 | } | ||
| 1569 | err = request_irq(vipi, mpic_ipi_action, | ||
| 1570 | IRQF_DISABLED|IRQF_PERCPU, | ||
| 1571 | ipi_names[i], (void *)i); | ||
| 1572 | if (err) { | ||
| 1573 | printk(KERN_ERR "Request of irq %d for IPI %ld failed\n", | ||
| 1574 | vipi, i); | ||
| 1575 | break; | ||
| 1576 | } | 1551 | } |
| 1552 | smp_request_message_ipi(vipi, i); | ||
| 1577 | } | 1553 | } |
| 1578 | } | 1554 | } |
| 1579 | 1555 | ||
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index d3e4d61030b5..77fae5f64f2e 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
| @@ -194,11 +194,41 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, | |||
| 194 | * 4xx PCI 2.x part | 194 | * 4xx PCI 2.x part |
| 195 | */ | 195 | */ |
| 196 | 196 | ||
| 197 | static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose, | ||
| 198 | void __iomem *reg, | ||
| 199 | u64 plb_addr, | ||
| 200 | u64 pci_addr, | ||
| 201 | u64 size, | ||
| 202 | unsigned int flags, | ||
| 203 | int index) | ||
| 204 | { | ||
| 205 | u32 ma, pcila, pciha; | ||
| 206 | |||
| 207 | if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || | ||
| 208 | size < 0x1000 || (plb_addr & (size - 1)) != 0) { | ||
| 209 | printk(KERN_WARNING "%s: Resource out of range\n", | ||
| 210 | hose->dn->full_name); | ||
| 211 | return -1; | ||
| 212 | } | ||
| 213 | ma = (0xffffffffu << ilog2(size)) | 1; | ||
| 214 | if (flags & IORESOURCE_PREFETCH) | ||
| 215 | ma |= 2; | ||
| 216 | |||
| 217 | pciha = RES_TO_U32_HIGH(pci_addr); | ||
| 218 | pcila = RES_TO_U32_LOW(pci_addr); | ||
| 219 | |||
| 220 | writel(plb_addr, reg + PCIL0_PMM0LA + (0x10 * index)); | ||
| 221 | writel(pcila, reg + PCIL0_PMM0PCILA + (0x10 * index)); | ||
| 222 | writel(pciha, reg + PCIL0_PMM0PCIHA + (0x10 * index)); | ||
| 223 | writel(ma, reg + PCIL0_PMM0MA + (0x10 * index)); | ||
| 224 | |||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 197 | static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, | 228 | static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, |
| 198 | void __iomem *reg) | 229 | void __iomem *reg) |
| 199 | { | 230 | { |
| 200 | u32 la, ma, pcila, pciha; | 231 | int i, j, found_isa_hole = 0; |
| 201 | int i, j; | ||
| 202 | 232 | ||
| 203 | /* Setup outbound memory windows */ | 233 | /* Setup outbound memory windows */ |
| 204 | for (i = j = 0; i < 3; i++) { | 234 | for (i = j = 0; i < 3; i++) { |
| @@ -213,28 +243,29 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, | |||
| 213 | break; | 243 | break; |
| 214 | } | 244 | } |
| 215 | 245 | ||
| 216 | /* Calculate register values */ | 246 | /* Configure the resource */ |
| 217 | la = res->start; | 247 | if (ppc4xx_setup_one_pci_PMM(hose, reg, |
| 218 | pciha = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset); | 248 | res->start, |
| 219 | pcila = RES_TO_U32_LOW(res->start - hose->pci_mem_offset); | 249 | res->start - hose->pci_mem_offset, |
| 220 | 250 | res->end + 1 - res->start, | |
| 221 | ma = res->end + 1 - res->start; | 251 | res->flags, |
| 222 | if (!is_power_of_2(ma) || ma < 0x1000 || ma > 0xffffffffu) { | 252 | j) == 0) { |
| 223 | printk(KERN_WARNING "%s: Resource out of range\n", | 253 | j++; |
| 224 | hose->dn->full_name); | 254 | |
| 225 | continue; | 255 | /* If the resource PCI address is 0 then we have our |
| 256 | * ISA memory hole | ||
| 257 | */ | ||
| 258 | if (res->start == hose->pci_mem_offset) | ||
| 259 | found_isa_hole = 1; | ||
| 226 | } | 260 | } |
| 227 | ma = (0xffffffffu << ilog2(ma)) | 0x1; | ||
| 228 | if (res->flags & IORESOURCE_PREFETCH) | ||
| 229 | ma |= 0x2; | ||
| 230 | |||
| 231 | /* Program register values */ | ||
| 232 | writel(la, reg + PCIL0_PMM0LA + (0x10 * j)); | ||
| 233 | writel(pcila, reg + PCIL0_PMM0PCILA + (0x10 * j)); | ||
| 234 | writel(pciha, reg + PCIL0_PMM0PCIHA + (0x10 * j)); | ||
| 235 | writel(ma, reg + PCIL0_PMM0MA + (0x10 * j)); | ||
| 236 | j++; | ||
| 237 | } | 261 | } |
| 262 | |||
| 263 | /* Handle ISA memory hole if not already covered */ | ||
| 264 | if (j <= 2 && !found_isa_hole && hose->isa_mem_size) | ||
| 265 | if (ppc4xx_setup_one_pci_PMM(hose, reg, hose->isa_mem_phys, 0, | ||
| 266 | hose->isa_mem_size, 0, j) == 0) | ||
| 267 | printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", | ||
| 268 | hose->dn->full_name); | ||
| 238 | } | 269 | } |
| 239 | 270 | ||
| 240 | static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose, | 271 | static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose, |
| @@ -352,11 +383,52 @@ static void __init ppc4xx_probe_pci_bridge(struct device_node *np) | |||
| 352 | * 4xx PCI-X part | 383 | * 4xx PCI-X part |
| 353 | */ | 384 | */ |
| 354 | 385 | ||
| 386 | static int __init ppc4xx_setup_one_pcix_POM(struct pci_controller *hose, | ||
| 387 | void __iomem *reg, | ||
| 388 | u64 plb_addr, | ||
| 389 | u64 pci_addr, | ||
| 390 | u64 size, | ||
| 391 | unsigned int flags, | ||
| 392 | int index) | ||
| 393 | { | ||
| 394 | u32 lah, lal, pciah, pcial, sa; | ||
| 395 | |||
| 396 | if (!is_power_of_2(size) || size < 0x1000 || | ||
| 397 | (plb_addr & (size - 1)) != 0) { | ||
| 398 | printk(KERN_WARNING "%s: Resource out of range\n", | ||
| 399 | hose->dn->full_name); | ||
| 400 | return -1; | ||
| 401 | } | ||
| 402 | |||
| 403 | /* Calculate register values */ | ||
| 404 | lah = RES_TO_U32_HIGH(plb_addr); | ||
| 405 | lal = RES_TO_U32_LOW(plb_addr); | ||
| 406 | pciah = RES_TO_U32_HIGH(pci_addr); | ||
| 407 | pcial = RES_TO_U32_LOW(pci_addr); | ||
| 408 | sa = (0xffffffffu << ilog2(size)) | 0x1; | ||
| 409 | |||
| 410 | /* Program register values */ | ||
| 411 | if (index == 0) { | ||
| 412 | writel(lah, reg + PCIX0_POM0LAH); | ||
| 413 | writel(lal, reg + PCIX0_POM0LAL); | ||
| 414 | writel(pciah, reg + PCIX0_POM0PCIAH); | ||
| 415 | writel(pcial, reg + PCIX0_POM0PCIAL); | ||
| 416 | writel(sa, reg + PCIX0_POM0SA); | ||
| 417 | } else { | ||
| 418 | writel(lah, reg + PCIX0_POM1LAH); | ||
| 419 | writel(lal, reg + PCIX0_POM1LAL); | ||
| 420 | writel(pciah, reg + PCIX0_POM1PCIAH); | ||
| 421 | writel(pcial, reg + PCIX0_POM1PCIAL); | ||
| 422 | writel(sa, reg + PCIX0_POM1SA); | ||
| 423 | } | ||
| 424 | |||
| 425 | return 0; | ||
| 426 | } | ||
| 427 | |||
| 355 | static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, | 428 | static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, |
| 356 | void __iomem *reg) | 429 | void __iomem *reg) |
| 357 | { | 430 | { |
| 358 | u32 lah, lal, pciah, pcial, sa; | 431 | int i, j, found_isa_hole = 0; |
| 359 | int i, j; | ||
| 360 | 432 | ||
| 361 | /* Setup outbound memory windows */ | 433 | /* Setup outbound memory windows */ |
| 362 | for (i = j = 0; i < 3; i++) { | 434 | for (i = j = 0; i < 3; i++) { |
| @@ -371,36 +443,29 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, | |||
| 371 | break; | 443 | break; |
| 372 | } | 444 | } |
| 373 | 445 | ||
| 374 | /* Calculate register values */ | 446 | /* Configure the resource */ |
| 375 | lah = RES_TO_U32_HIGH(res->start); | 447 | if (ppc4xx_setup_one_pcix_POM(hose, reg, |
| 376 | lal = RES_TO_U32_LOW(res->start); | 448 | res->start, |
| 377 | pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset); | 449 | res->start - hose->pci_mem_offset, |
| 378 | pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset); | 450 | res->end + 1 - res->start, |
| 379 | sa = res->end + 1 - res->start; | 451 | res->flags, |
| 380 | if (!is_power_of_2(sa) || sa < 0x100000 || | 452 | j) == 0) { |
| 381 | sa > 0xffffffffu) { | 453 | j++; |
| 382 | printk(KERN_WARNING "%s: Resource out of range\n", | 454 | |
| 383 | hose->dn->full_name); | 455 | /* If the resource PCI address is 0 then we have our |
| 384 | continue; | 456 | * ISA memory hole |
| 457 | */ | ||
| 458 | if (res->start == hose->pci_mem_offset) | ||
| 459 | found_isa_hole = 1; | ||
| 385 | } | 460 | } |
| 386 | sa = (0xffffffffu << ilog2(sa)) | 0x1; | ||
| 387 | |||
| 388 | /* Program register values */ | ||
| 389 | if (j == 0) { | ||
| 390 | writel(lah, reg + PCIX0_POM0LAH); | ||
| 391 | writel(lal, reg + PCIX0_POM0LAL); | ||
| 392 | writel(pciah, reg + PCIX0_POM0PCIAH); | ||
| 393 | writel(pcial, reg + PCIX0_POM0PCIAL); | ||
| 394 | writel(sa, reg + PCIX0_POM0SA); | ||
| 395 | } else { | ||
| 396 | writel(lah, reg + PCIX0_POM1LAH); | ||
| 397 | writel(lal, reg + PCIX0_POM1LAL); | ||
| 398 | writel(pciah, reg + PCIX0_POM1PCIAH); | ||
| 399 | writel(pcial, reg + PCIX0_POM1PCIAL); | ||
| 400 | writel(sa, reg + PCIX0_POM1SA); | ||
| 401 | } | ||
| 402 | j++; | ||
| 403 | } | 461 | } |
| 462 | |||
| 463 | /* Handle ISA memory hole if not already covered */ | ||
| 464 | if (j <= 1 && !found_isa_hole && hose->isa_mem_size) | ||
| 465 | if (ppc4xx_setup_one_pcix_POM(hose, reg, hose->isa_mem_phys, 0, | ||
| 466 | hose->isa_mem_size, 0, j) == 0) | ||
| 467 | printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", | ||
| 468 | hose->dn->full_name); | ||
| 404 | } | 469 | } |
| 405 | 470 | ||
| 406 | static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose, | 471 | static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose, |
| @@ -1317,12 +1382,72 @@ static struct pci_ops ppc4xx_pciex_pci_ops = | |||
| 1317 | .write = ppc4xx_pciex_write_config, | 1382 | .write = ppc4xx_pciex_write_config, |
| 1318 | }; | 1383 | }; |
| 1319 | 1384 | ||
| 1385 | static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, | ||
| 1386 | struct pci_controller *hose, | ||
| 1387 | void __iomem *mbase, | ||
| 1388 | u64 plb_addr, | ||
| 1389 | u64 pci_addr, | ||
| 1390 | u64 size, | ||
| 1391 | unsigned int flags, | ||
| 1392 | int index) | ||
| 1393 | { | ||
| 1394 | u32 lah, lal, pciah, pcial, sa; | ||
| 1395 | |||
| 1396 | if (!is_power_of_2(size) || | ||
| 1397 | (index < 2 && size < 0x100000) || | ||
| 1398 | (index == 2 && size < 0x100) || | ||
| 1399 | (plb_addr & (size - 1)) != 0) { | ||
| 1400 | printk(KERN_WARNING "%s: Resource out of range\n", | ||
| 1401 | hose->dn->full_name); | ||
| 1402 | return -1; | ||
| 1403 | } | ||
| 1404 | |||
| 1405 | /* Calculate register values */ | ||
| 1406 | lah = RES_TO_U32_HIGH(plb_addr); | ||
| 1407 | lal = RES_TO_U32_LOW(plb_addr); | ||
| 1408 | pciah = RES_TO_U32_HIGH(pci_addr); | ||
| 1409 | pcial = RES_TO_U32_LOW(pci_addr); | ||
| 1410 | sa = (0xffffffffu << ilog2(size)) | 0x1; | ||
| 1411 | |||
| 1412 | /* Program register values */ | ||
| 1413 | switch (index) { | ||
| 1414 | case 0: | ||
| 1415 | out_le32(mbase + PECFG_POM0LAH, pciah); | ||
| 1416 | out_le32(mbase + PECFG_POM0LAL, pcial); | ||
| 1417 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); | ||
| 1418 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); | ||
| 1419 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); | ||
| 1420 | /* Note that 3 here means enabled | single region */ | ||
| 1421 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3); | ||
| 1422 | break; | ||
| 1423 | case 1: | ||
| 1424 | out_le32(mbase + PECFG_POM1LAH, pciah); | ||
| 1425 | out_le32(mbase + PECFG_POM1LAL, pcial); | ||
| 1426 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); | ||
| 1427 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); | ||
| 1428 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); | ||
| 1429 | /* Note that 3 here means enabled | single region */ | ||
| 1430 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3); | ||
| 1431 | break; | ||
| 1432 | case 2: | ||
| 1433 | out_le32(mbase + PECFG_POM2LAH, pciah); | ||
| 1434 | out_le32(mbase + PECFG_POM2LAL, pcial); | ||
| 1435 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah); | ||
| 1436 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); | ||
| 1437 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); | ||
| 1438 | /* Note that 3 here means enabled | IO space !!! */ | ||
| 1439 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, sa | 3); | ||
| 1440 | break; | ||
| 1441 | } | ||
| 1442 | |||
| 1443 | return 0; | ||
| 1444 | } | ||
| 1445 | |||
| 1320 | static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, | 1446 | static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, |
| 1321 | struct pci_controller *hose, | 1447 | struct pci_controller *hose, |
| 1322 | void __iomem *mbase) | 1448 | void __iomem *mbase) |
| 1323 | { | 1449 | { |
| 1324 | u32 lah, lal, pciah, pcial, sa; | 1450 | int i, j, found_isa_hole = 0; |
| 1325 | int i, j; | ||
| 1326 | 1451 | ||
| 1327 | /* Setup outbound memory windows */ | 1452 | /* Setup outbound memory windows */ |
| 1328 | for (i = j = 0; i < 3; i++) { | 1453 | for (i = j = 0; i < 3; i++) { |
| @@ -1337,53 +1462,38 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, | |||
| 1337 | break; | 1462 | break; |
| 1338 | } | 1463 | } |
| 1339 | 1464 | ||
| 1340 | /* Calculate register values */ | 1465 | /* Configure the resource */ |
| 1341 | lah = RES_TO_U32_HIGH(res->start); | 1466 | if (ppc4xx_setup_one_pciex_POM(port, hose, mbase, |
| 1342 | lal = RES_TO_U32_LOW(res->start); | 1467 | res->start, |
| 1343 | pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset); | 1468 | res->start - hose->pci_mem_offset, |
| 1344 | pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset); | 1469 | res->end + 1 - res->start, |
| 1345 | sa = res->end + 1 - res->start; | 1470 | res->flags, |
| 1346 | if (!is_power_of_2(sa) || sa < 0x100000 || | 1471 | j) == 0) { |
| 1347 | sa > 0xffffffffu) { | 1472 | j++; |
| 1348 | printk(KERN_WARNING "%s: Resource out of range\n", | 1473 | |
| 1349 | port->node->full_name); | 1474 | /* If the resource PCI address is 0 then we have our |
| 1350 | continue; | 1475 | * ISA memory hole |
| 1351 | } | 1476 | */ |
| 1352 | sa = (0xffffffffu << ilog2(sa)) | 0x1; | 1477 | if (res->start == hose->pci_mem_offset) |
| 1353 | 1478 | found_isa_hole = 1; | |
| 1354 | /* Program register values */ | ||
| 1355 | switch (j) { | ||
| 1356 | case 0: | ||
| 1357 | out_le32(mbase + PECFG_POM0LAH, pciah); | ||
| 1358 | out_le32(mbase + PECFG_POM0LAL, pcial); | ||
| 1359 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); | ||
| 1360 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); | ||
| 1361 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); | ||
| 1362 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3); | ||
| 1363 | break; | ||
| 1364 | case 1: | ||
| 1365 | out_le32(mbase + PECFG_POM1LAH, pciah); | ||
| 1366 | out_le32(mbase + PECFG_POM1LAL, pcial); | ||
| 1367 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); | ||
| 1368 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); | ||
| 1369 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); | ||
| 1370 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3); | ||
| 1371 | break; | ||
| 1372 | } | 1479 | } |
| 1373 | j++; | ||
| 1374 | } | 1480 | } |
| 1375 | 1481 | ||
| 1376 | /* Configure IO, always 64K starting at 0 */ | 1482 | /* Handle ISA memory hole if not already covered */ |
| 1377 | if (hose->io_resource.flags & IORESOURCE_IO) { | 1483 | if (j <= 1 && !found_isa_hole && hose->isa_mem_size) |
| 1378 | lah = RES_TO_U32_HIGH(hose->io_base_phys); | 1484 | if (ppc4xx_setup_one_pciex_POM(port, hose, mbase, |
| 1379 | lal = RES_TO_U32_LOW(hose->io_base_phys); | 1485 | hose->isa_mem_phys, 0, |
| 1380 | out_le32(mbase + PECFG_POM2LAH, 0); | 1486 | hose->isa_mem_size, 0, j) == 0) |
| 1381 | out_le32(mbase + PECFG_POM2LAL, 0); | 1487 | printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", |
| 1382 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah); | 1488 | hose->dn->full_name); |
| 1383 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); | 1489 | |
| 1384 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); | 1490 | /* Configure IO, always 64K starting at 0. We hard wire it to 64K ! |
| 1385 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0xffff0000 | 3); | 1491 | * Note also that it -has- to be region index 2 on this HW |
| 1386 | } | 1492 | */ |
| 1493 | if (hose->io_resource.flags & IORESOURCE_IO) | ||
| 1494 | ppc4xx_setup_one_pciex_POM(port, hose, mbase, | ||
| 1495 | hose->io_base_phys, 0, | ||
| 1496 | 0x10000, IORESOURCE_IO, 2); | ||
| 1387 | } | 1497 | } |
| 1388 | 1498 | ||
| 1389 | static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, | 1499 | static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, |
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index b3b73ae57d6d..01bce3784b0a 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 20 | #include <linux/param.h> | 20 | #include <linux/param.h> |
| 21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
| 22 | #include <linux/spinlock.h> | ||
| 22 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
| 23 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
| 24 | #include <linux/bootmem.h> | 25 | #include <linux/bootmem.h> |
| @@ -38,6 +39,8 @@ static void qe_snums_init(void); | |||
| 38 | static int qe_sdma_init(void); | 39 | static int qe_sdma_init(void); |
| 39 | 40 | ||
| 40 | static DEFINE_SPINLOCK(qe_lock); | 41 | static DEFINE_SPINLOCK(qe_lock); |
| 42 | DEFINE_SPINLOCK(cmxgcr_lock); | ||
| 43 | EXPORT_SYMBOL(cmxgcr_lock); | ||
| 41 | 44 | ||
| 42 | /* QE snum state */ | 45 | /* QE snum state */ |
| 43 | enum qe_snum_state { | 46 | enum qe_snum_state { |
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c index 1d78071aad7d..ebb442ea1917 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc.c +++ b/arch/powerpc/sysdev/qe_lib/ucc.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include <linux/stddef.h> | 20 | #include <linux/stddef.h> |
| 21 | #include <linux/spinlock.h> | ||
| 21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 22 | 23 | ||
| 23 | #include <asm/irq.h> | 24 | #include <asm/irq.h> |
| @@ -26,9 +27,6 @@ | |||
| 26 | #include <asm/qe.h> | 27 | #include <asm/qe.h> |
| 27 | #include <asm/ucc.h> | 28 | #include <asm/ucc.h> |
| 28 | 29 | ||
| 29 | DEFINE_SPINLOCK(cmxgcr_lock); | ||
| 30 | EXPORT_SYMBOL(cmxgcr_lock); | ||
| 31 | |||
| 32 | int ucc_set_qe_mux_mii_mng(unsigned int ucc_num) | 30 | int ucc_set_qe_mux_mii_mng(unsigned int ucc_num) |
| 33 | { | 31 | { |
| 34 | unsigned long flags; | 32 | unsigned long flags; |
