aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/include/asm/futex.h31
-rw-r--r--arch/microblaze/include/asm/pci-bridge.h12
-rw-r--r--arch/microblaze/include/asm/prom.h15
-rw-r--r--arch/microblaze/kernel/prom_parse.c77
-rw-r--r--arch/microblaze/pci/pci-common.c1
5 files changed, 30 insertions, 106 deletions
diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h
index ad3fd61b2fe7..b0526d2716fa 100644
--- a/arch/microblaze/include/asm/futex.h
+++ b/arch/microblaze/include/asm/futex.h
@@ -29,7 +29,7 @@
29}) 29})
30 30
31static inline int 31static inline int
32futex_atomic_op_inuser(int encoded_op, int __user *uaddr) 32futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
33{ 33{
34 int op = (encoded_op >> 28) & 7; 34 int op = (encoded_op >> 28) & 7;
35 int cmp = (encoded_op >> 24) & 15; 35 int cmp = (encoded_op >> 24) & 15;
@@ -39,7 +39,7 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
39 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) 39 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
40 oparg = 1 << oparg; 40 oparg = 1 << oparg;
41 41
42 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) 42 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
43 return -EFAULT; 43 return -EFAULT;
44 44
45 pagefault_disable(); 45 pagefault_disable();
@@ -94,31 +94,34 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
94} 94}
95 95
96static inline int 96static inline int
97futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) 97futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
98 u32 oldval, u32 newval)
98{ 99{
99 int prev, cmp; 100 int ret = 0, cmp;
101 u32 prev;
100 102
101 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) 103 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
102 return -EFAULT; 104 return -EFAULT;
103 105
104 __asm__ __volatile__ ("1: lwx %0, %2, r0; \ 106 __asm__ __volatile__ ("1: lwx %1, %3, r0; \
105 cmp %1, %0, %3; \ 107 cmp %2, %1, %4; \
106 beqi %1, 3f; \ 108 beqi %2, 3f; \
107 2: swx %4, %2, r0; \ 109 2: swx %5, %3, r0; \
108 addic %1, r0, 0; \ 110 addic %2, r0, 0; \
109 bnei %1, 1b; \ 111 bnei %2, 1b; \
110 3: \ 112 3: \
111 .section .fixup,\"ax\"; \ 113 .section .fixup,\"ax\"; \
112 4: brid 3b; \ 114 4: brid 3b; \
113 addik %0, r0, %5; \ 115 addik %0, r0, %6; \
114 .previous; \ 116 .previous; \
115 .section __ex_table,\"a\"; \ 117 .section __ex_table,\"a\"; \
116 .word 1b,4b,2b,4b; \ 118 .word 1b,4b,2b,4b; \
117 .previous;" \ 119 .previous;" \
118 : "=&r" (prev), "=&r"(cmp) \ 120 : "+r" (ret), "=&r" (prev), "=&r"(cmp) \
119 : "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT)); 121 : "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT));
120 122
121 return prev; 123 *uval = prev;
124 return ret;
122} 125}
123 126
124#endif /* __KERNEL__ */ 127#endif /* __KERNEL__ */
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index 0c68764ab547..10717669e0c2 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -104,11 +104,22 @@ struct pci_controller {
104 int global_number; /* PCI domain number */ 104 int global_number; /* PCI domain number */
105}; 105};
106 106
107#ifdef CONFIG_PCI
107static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) 108static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
108{ 109{
109 return bus->sysdata; 110 return bus->sysdata;
110} 111}
111 112
113static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
114{
115 struct pci_controller *host;
116
117 if (bus->self)
118 return pci_device_to_OF_node(bus->self);
119 host = pci_bus_to_host(bus);
120 return host ? host->dn : NULL;
121}
122
112static inline int isa_vaddr_is_ioport(void __iomem *address) 123static inline int isa_vaddr_is_ioport(void __iomem *address)
113{ 124{
114 /* No specific ISA handling on ppc32 at this stage, it 125 /* No specific ISA handling on ppc32 at this stage, it
@@ -116,6 +127,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
116 */ 127 */
117 return 0; 128 return 0;
118} 129}
130#endif /* CONFIG_PCI */
119 131
120/* These are used for config access before all the PCI probing 132/* These are used for config access before all the PCI probing
121 has been done. */ 133 has been done. */
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 2e72af078b05..d0890d36ef61 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -64,21 +64,6 @@ extern void kdump_move_device_tree(void);
64/* CPU OF node matching */ 64/* CPU OF node matching */
65struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); 65struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
66 66
67/**
68 * of_irq_map_pci - Resolve the interrupt for a PCI device
69 * @pdev: the device whose interrupt is to be resolved
70 * @out_irq: structure of_irq filled by this function
71 *
72 * This function resolves the PCI interrupt for a given PCI device. If a
73 * device-node exists for a given pci_dev, it will use normal OF tree
74 * walking. If not, it will implement standard swizzling and walk up the
75 * PCI tree until an device-node is found, at which point it will finish
76 * resolving using the OF tree walking.
77 */
78struct pci_dev;
79struct of_irq;
80extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
81
82#endif /* __ASSEMBLY__ */ 67#endif /* __ASSEMBLY__ */
83#endif /* __KERNEL__ */ 68#endif /* __KERNEL__ */
84 69
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 9ae24f4b882b..47187cc2cf00 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -2,88 +2,11 @@
2 2
3#include <linux/kernel.h> 3#include <linux/kernel.h>
4#include <linux/string.h> 4#include <linux/string.h>
5#include <linux/pci_regs.h>
6#include <linux/module.h> 5#include <linux/module.h>
7#include <linux/ioport.h> 6#include <linux/ioport.h>
8#include <linux/etherdevice.h> 7#include <linux/etherdevice.h>
9#include <linux/of_address.h> 8#include <linux/of_address.h>
10#include <asm/prom.h> 9#include <asm/prom.h>
11#include <asm/pci-bridge.h>
12
13#ifdef CONFIG_PCI
14int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
15{
16 struct device_node *dn, *ppnode;
17 struct pci_dev *ppdev;
18 u32 lspec;
19 u32 laddr[3];
20 u8 pin;
21 int rc;
22
23 /* Check if we have a device node, if yes, fallback to standard OF
24 * parsing
25 */
26 dn = pci_device_to_OF_node(pdev);
27 if (dn)
28 return of_irq_map_one(dn, 0, out_irq);
29
30 /* Ok, we don't, time to have fun. Let's start by building up an
31 * interrupt spec. we assume #interrupt-cells is 1, which is standard
32 * for PCI. If you do different, then don't use that routine.
33 */
34 rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
35 if (rc != 0)
36 return rc;
37 /* No pin, exit */
38 if (pin == 0)
39 return -ENODEV;
40
41 /* Now we walk up the PCI tree */
42 lspec = pin;
43 for (;;) {
44 /* Get the pci_dev of our parent */
45 ppdev = pdev->bus->self;
46
47 /* Ouch, it's a host bridge... */
48 if (ppdev == NULL) {
49 struct pci_controller *host;
50 host = pci_bus_to_host(pdev->bus);
51 ppnode = host ? host->dn : NULL;
52 /* No node for host bridge ? give up */
53 if (ppnode == NULL)
54 return -EINVAL;
55 } else
56 /* We found a P2P bridge, check if it has a node */
57 ppnode = pci_device_to_OF_node(ppdev);
58
59 /* Ok, we have found a parent with a device-node, hand over to
60 * the OF parsing code.
61 * We build a unit address from the linux device to be used for
62 * resolution. Note that we use the linux bus number which may
63 * not match your firmware bus numbering.
64 * Fortunately, in most cases, interrupt-map-mask doesn't
65 * include the bus number as part of the matching.
66 * You should still be careful about that though if you intend
67 * to rely on this function (you ship a firmware that doesn't
68 * create device nodes for all PCI devices).
69 */
70 if (ppnode)
71 break;
72
73 /* We can only get here if we hit a P2P bridge with no node,
74 * let's do standard swizzling and try again
75 */
76 lspec = pci_swizzle_interrupt_pin(pdev, lspec);
77 pdev = ppdev;
78 }
79
80 laddr[0] = (pdev->bus->number << 16)
81 | (pdev->devfn << 8);
82 laddr[1] = laddr[2] = 0;
83 return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
84}
85EXPORT_SYMBOL_GPL(of_irq_map_pci);
86#endif /* CONFIG_PCI */
87 10
88void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, 11void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
89 unsigned long *busno, unsigned long *phys, unsigned long *size) 12 unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index e363615d6798..1e01a1253631 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -29,6 +29,7 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/of.h> 30#include <linux/of.h>
31#include <linux/of_address.h> 31#include <linux/of_address.h>
32#include <linux/of_pci.h>
32 33
33#include <asm/processor.h> 34#include <asm/processor.h>
34#include <asm/io.h> 35#include <asm/io.h>