aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/qe_lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/qe_lib')
-rw-r--r--arch/powerpc/sysdev/qe_lib/Kconfig13
-rw-r--r--arch/powerpc/sysdev/qe_lib/Makefile2
-rw-r--r--arch/powerpc/sysdev/qe_lib/gpio.c149
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c94
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c14
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_io.c94
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc.c7
-rw-r--r--arch/powerpc/sysdev/qe_lib/usb.c55
8 files changed, 275 insertions, 153 deletions
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig
index adc66212a419..4bb18f57901e 100644
--- a/arch/powerpc/sysdev/qe_lib/Kconfig
+++ b/arch/powerpc/sysdev/qe_lib/Kconfig
@@ -20,3 +20,16 @@ config UCC
20 bool 20 bool
21 default y if UCC_FAST || UCC_SLOW 21 default y if UCC_FAST || UCC_SLOW
22 22
23config QE_USB
24 bool
25 help
26 QE USB Host Controller support
27
28config QE_GPIO
29 bool "QE GPIO support"
30 depends on QUICC_ENGINE
31 select GENERIC_GPIO
32 select HAVE_GPIO_LIB
33 help
34 Say Y here if you're going to use hardware that connects to the
35 QE GPIOs.
diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/arch/powerpc/sysdev/qe_lib/Makefile
index 874fe1a5b1cf..f1855c185291 100644
--- a/arch/powerpc/sysdev/qe_lib/Makefile
+++ b/arch/powerpc/sysdev/qe_lib/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o
6obj-$(CONFIG_UCC) += ucc.o 6obj-$(CONFIG_UCC) += ucc.o
7obj-$(CONFIG_UCC_SLOW) += ucc_slow.o 7obj-$(CONFIG_UCC_SLOW) += ucc_slow.o
8obj-$(CONFIG_UCC_FAST) += ucc_fast.o 8obj-$(CONFIG_UCC_FAST) += ucc_fast.o
9obj-$(CONFIG_QE_USB) += usb.o
10obj-$(CONFIG_QE_GPIO) += gpio.o
diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c
new file mode 100644
index 000000000000..8e5a0bc36d0b
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/gpio.c
@@ -0,0 +1,149 @@
1/*
2 * QUICC Engine GPIOs
3 *
4 * Copyright (c) MontaVista Software, Inc. 2008.
5 *
6 * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/spinlock.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include <linux/of_gpio.h>
20#include <linux/gpio.h>
21#include <asm/qe.h>
22
23struct qe_gpio_chip {
24 struct of_mm_gpio_chip mm_gc;
25 spinlock_t lock;
26
27 /* shadowed data register to clear/set bits safely */
28 u32 cpdata;
29};
30
31static inline struct qe_gpio_chip *
32to_qe_gpio_chip(struct of_mm_gpio_chip *mm_gc)
33{
34 return container_of(mm_gc, struct qe_gpio_chip, mm_gc);
35}
36
37static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
38{
39 struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
40 struct qe_pio_regs __iomem *regs = mm_gc->regs;
41
42 qe_gc->cpdata = in_be32(&regs->cpdata);
43}
44
45static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
46{
47 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
48 struct qe_pio_regs __iomem *regs = mm_gc->regs;
49 u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio);
50
51 return in_be32(&regs->cpdata) & pin_mask;
52}
53
54static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
55{
56 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
57 struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
58 struct qe_pio_regs __iomem *regs = mm_gc->regs;
59 unsigned long flags;
60 u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio);
61
62 spin_lock_irqsave(&qe_gc->lock, flags);
63
64 if (val)
65 qe_gc->cpdata |= pin_mask;
66 else
67 qe_gc->cpdata &= ~pin_mask;
68
69 out_be32(&regs->cpdata, qe_gc->cpdata);
70
71 spin_unlock_irqrestore(&qe_gc->lock, flags);
72}
73
74static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
75{
76 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
77 struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
78 unsigned long flags;
79
80 spin_lock_irqsave(&qe_gc->lock, flags);
81
82 __par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_IN, 0, 0, 0);
83
84 spin_unlock_irqrestore(&qe_gc->lock, flags);
85
86 return 0;
87}
88
89static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
90{
91 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
92 struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
93 unsigned long flags;
94
95 spin_lock_irqsave(&qe_gc->lock, flags);
96
97 __par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0);
98
99 spin_unlock_irqrestore(&qe_gc->lock, flags);
100
101 qe_gpio_set(gc, gpio, val);
102
103 return 0;
104}
105
106static int __init qe_add_gpiochips(void)
107{
108 struct device_node *np;
109
110 for_each_compatible_node(np, NULL, "fsl,mpc8323-qe-pario-bank") {
111 int ret;
112 struct qe_gpio_chip *qe_gc;
113 struct of_mm_gpio_chip *mm_gc;
114 struct of_gpio_chip *of_gc;
115 struct gpio_chip *gc;
116
117 qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL);
118 if (!qe_gc) {
119 ret = -ENOMEM;
120 goto err;
121 }
122
123 spin_lock_init(&qe_gc->lock);
124
125 mm_gc = &qe_gc->mm_gc;
126 of_gc = &mm_gc->of_gc;
127 gc = &of_gc->gc;
128
129 mm_gc->save_regs = qe_gpio_save_regs;
130 of_gc->gpio_cells = 2;
131 gc->ngpio = QE_PIO_PINS;
132 gc->direction_input = qe_gpio_dir_in;
133 gc->direction_output = qe_gpio_dir_out;
134 gc->get = qe_gpio_get;
135 gc->set = qe_gpio_set;
136
137 ret = of_mm_gpiochip_add(np, mm_gc);
138 if (ret)
139 goto err;
140 continue;
141err:
142 pr_err("%s: registration failed with status %d\n",
143 np->full_name, ret);
144 kfree(qe_gc);
145 /* try others anyway */
146 }
147 return 0;
148}
149arch_initcall(qe_add_gpiochips);
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index cff550eec7e8..9e82d7e725a5 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -35,7 +35,6 @@
35#include <asm/rheap.h> 35#include <asm/rheap.h>
36 36
37static void qe_snums_init(void); 37static void qe_snums_init(void);
38static void qe_muram_init(void);
39static int qe_sdma_init(void); 38static int qe_sdma_init(void);
40 39
41static DEFINE_SPINLOCK(qe_lock); 40static DEFINE_SPINLOCK(qe_lock);
@@ -88,7 +87,7 @@ phys_addr_t get_qe_base(void)
88 87
89EXPORT_SYMBOL(get_qe_base); 88EXPORT_SYMBOL(get_qe_base);
90 89
91void qe_reset(void) 90void __init qe_reset(void)
92{ 91{
93 if (qe_immr == NULL) 92 if (qe_immr == NULL)
94 qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE); 93 qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
@@ -325,97 +324,6 @@ static int qe_sdma_init(void)
325 return 0; 324 return 0;
326} 325}
327 326
328/*
329 * muram_alloc / muram_free bits.
330 */
331static DEFINE_SPINLOCK(qe_muram_lock);
332
333/* 16 blocks should be enough to satisfy all requests
334 * until the memory subsystem goes up... */
335static rh_block_t qe_boot_muram_rh_block[16];
336static rh_info_t qe_muram_info;
337
338static void qe_muram_init(void)
339{
340 struct device_node *np;
341 const u32 *address;
342 u64 size;
343 unsigned int flags;
344
345 /* initialize the info header */
346 rh_init(&qe_muram_info, 1,
347 sizeof(qe_boot_muram_rh_block) /
348 sizeof(qe_boot_muram_rh_block[0]), qe_boot_muram_rh_block);
349
350 /* Attach the usable muram area */
351 /* XXX: This is a subset of the available muram. It
352 * varies with the processor and the microcode patches activated.
353 */
354 np = of_find_compatible_node(NULL, NULL, "fsl,qe-muram-data");
355 if (!np) {
356 np = of_find_node_by_name(NULL, "data-only");
357 if (!np) {
358 WARN_ON(1);
359 return;
360 }
361 }
362
363 address = of_get_address(np, 0, &size, &flags);
364 WARN_ON(!address);
365
366 of_node_put(np);
367 if (address)
368 rh_attach_region(&qe_muram_info, *address, (int)size);
369}
370
371/* This function returns an index into the MURAM area.
372 */
373unsigned long qe_muram_alloc(int size, int align)
374{
375 unsigned long start;
376 unsigned long flags;
377
378 spin_lock_irqsave(&qe_muram_lock, flags);
379 start = rh_alloc_align(&qe_muram_info, size, align, "QE");
380 spin_unlock_irqrestore(&qe_muram_lock, flags);
381
382 return start;
383}
384EXPORT_SYMBOL(qe_muram_alloc);
385
386int qe_muram_free(unsigned long offset)
387{
388 int ret;
389 unsigned long flags;
390
391 spin_lock_irqsave(&qe_muram_lock, flags);
392 ret = rh_free(&qe_muram_info, offset);
393 spin_unlock_irqrestore(&qe_muram_lock, flags);
394
395 return ret;
396}
397EXPORT_SYMBOL(qe_muram_free);
398
399/* not sure if this is ever needed */
400unsigned long qe_muram_alloc_fixed(unsigned long offset, int size)
401{
402 unsigned long start;
403 unsigned long flags;
404
405 spin_lock_irqsave(&qe_muram_lock, flags);
406 start = rh_alloc_fixed(&qe_muram_info, offset, size, "commproc");
407 spin_unlock_irqrestore(&qe_muram_lock, flags);
408
409 return start;
410}
411EXPORT_SYMBOL(qe_muram_alloc_fixed);
412
413void qe_muram_dump(void)
414{
415 rh_dump(&qe_muram_info);
416}
417EXPORT_SYMBOL(qe_muram_dump);
418
419/* The maximum number of RISCs we support */ 327/* The maximum number of RISCs we support */
420#define MAX_QE_RISC 2 328#define MAX_QE_RISC 2
421 329
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index f59444d3be75..63cdf9887f36 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -329,21 +329,19 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
329 struct resource res; 329 struct resource res;
330 u32 temp = 0, ret, high_active = 0; 330 u32 temp = 0, ret, high_active = 0;
331 331
332 ret = of_address_to_resource(node, 0, &res);
333 if (ret)
334 return;
335
332 qe_ic = alloc_bootmem(sizeof(struct qe_ic)); 336 qe_ic = alloc_bootmem(sizeof(struct qe_ic));
333 if (qe_ic == NULL) 337 if (qe_ic == NULL)
334 return; 338 return;
335 339
336 memset(qe_ic, 0, sizeof(struct qe_ic)); 340 memset(qe_ic, 0, sizeof(struct qe_ic));
337 341
338 qe_ic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR, 342 qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
339 NR_QE_IC_INTS, &qe_ic_host_ops, 0); 343 NR_QE_IC_INTS, &qe_ic_host_ops, 0);
340 if (qe_ic->irqhost == NULL) { 344 if (qe_ic->irqhost == NULL)
341 of_node_put(node);
342 return;
343 }
344
345 ret = of_address_to_resource(node, 0, &res);
346 if (ret)
347 return; 345 return;
348 346
349 qe_ic->regs = ioremap(res.start, res.end - res.start + 1); 347 qe_ic->regs = ioremap(res.start, res.end - res.start + 1);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c
index 93916a48afec..7c87460179ef 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_io.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_io.c
@@ -28,21 +28,7 @@
28 28
29#undef DEBUG 29#undef DEBUG
30 30
31#define NUM_OF_PINS 32 31static struct qe_pio_regs __iomem *par_io;
32
33struct port_regs {
34 __be32 cpodr; /* Open drain register */
35 __be32 cpdata; /* Data register */
36 __be32 cpdir1; /* Direction register */
37 __be32 cpdir2; /* Direction register */
38 __be32 cppar1; /* Pin assignment register */
39 __be32 cppar2; /* Pin assignment register */
40#ifdef CONFIG_PPC_85xx
41 u8 pad[8];
42#endif
43};
44
45static struct port_regs __iomem *par_io;
46static int num_par_io_ports = 0; 32static int num_par_io_ports = 0;
47 33
48int par_io_init(struct device_node *np) 34int par_io_init(struct device_node *np)
@@ -64,69 +50,79 @@ int par_io_init(struct device_node *np)
64 return 0; 50 return 0;
65} 51}
66 52
67int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, 53void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir,
68 int assignment, int has_irq) 54 int open_drain, int assignment, int has_irq)
69{ 55{
70 u32 pin_mask1bit, pin_mask2bits, new_mask2bits, tmp_val; 56 u32 pin_mask1bit;
71 57 u32 pin_mask2bits;
72 if (!par_io) 58 u32 new_mask2bits;
73 return -1; 59 u32 tmp_val;
74 60
75 /* calculate pin location for single and 2 bits information */ 61 /* calculate pin location for single and 2 bits information */
76 pin_mask1bit = (u32) (1 << (NUM_OF_PINS - (pin + 1))); 62 pin_mask1bit = (u32) (1 << (QE_PIO_PINS - (pin + 1)));
77 63
78 /* Set open drain, if required */ 64 /* Set open drain, if required */
79 tmp_val = in_be32(&par_io[port].cpodr); 65 tmp_val = in_be32(&par_io->cpodr);
80 if (open_drain) 66 if (open_drain)
81 out_be32(&par_io[port].cpodr, pin_mask1bit | tmp_val); 67 out_be32(&par_io->cpodr, pin_mask1bit | tmp_val);
82 else 68 else
83 out_be32(&par_io[port].cpodr, ~pin_mask1bit & tmp_val); 69 out_be32(&par_io->cpodr, ~pin_mask1bit & tmp_val);
84 70
85 /* define direction */ 71 /* define direction */
86 tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ? 72 tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ?
87 in_be32(&par_io[port].cpdir2) : 73 in_be32(&par_io->cpdir2) :
88 in_be32(&par_io[port].cpdir1); 74 in_be32(&par_io->cpdir1);
89 75
90 /* get all bits mask for 2 bit per port */ 76 /* get all bits mask for 2 bit per port */
91 pin_mask2bits = (u32) (0x3 << (NUM_OF_PINS - 77 pin_mask2bits = (u32) (0x3 << (QE_PIO_PINS -
92 (pin % (NUM_OF_PINS / 2) + 1) * 2)); 78 (pin % (QE_PIO_PINS / 2) + 1) * 2));
93 79
94 /* Get the final mask we need for the right definition */ 80 /* Get the final mask we need for the right definition */
95 new_mask2bits = (u32) (dir << (NUM_OF_PINS - 81 new_mask2bits = (u32) (dir << (QE_PIO_PINS -
96 (pin % (NUM_OF_PINS / 2) + 1) * 2)); 82 (pin % (QE_PIO_PINS / 2) + 1) * 2));
97 83
98 /* clear and set 2 bits mask */ 84 /* clear and set 2 bits mask */
99 if (pin > (NUM_OF_PINS / 2) - 1) { 85 if (pin > (QE_PIO_PINS / 2) - 1) {
100 out_be32(&par_io[port].cpdir2, 86 out_be32(&par_io->cpdir2,
101 ~pin_mask2bits & tmp_val); 87 ~pin_mask2bits & tmp_val);
102 tmp_val &= ~pin_mask2bits; 88 tmp_val &= ~pin_mask2bits;
103 out_be32(&par_io[port].cpdir2, new_mask2bits | tmp_val); 89 out_be32(&par_io->cpdir2, new_mask2bits | tmp_val);
104 } else { 90 } else {
105 out_be32(&par_io[port].cpdir1, 91 out_be32(&par_io->cpdir1,
106 ~pin_mask2bits & tmp_val); 92 ~pin_mask2bits & tmp_val);
107 tmp_val &= ~pin_mask2bits; 93 tmp_val &= ~pin_mask2bits;
108 out_be32(&par_io[port].cpdir1, new_mask2bits | tmp_val); 94 out_be32(&par_io->cpdir1, new_mask2bits | tmp_val);
109 } 95 }
110 /* define pin assignment */ 96 /* define pin assignment */
111 tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ? 97 tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ?
112 in_be32(&par_io[port].cppar2) : 98 in_be32(&par_io->cppar2) :
113 in_be32(&par_io[port].cppar1); 99 in_be32(&par_io->cppar1);
114 100
115 new_mask2bits = (u32) (assignment << (NUM_OF_PINS - 101 new_mask2bits = (u32) (assignment << (QE_PIO_PINS -
116 (pin % (NUM_OF_PINS / 2) + 1) * 2)); 102 (pin % (QE_PIO_PINS / 2) + 1) * 2));
117 /* clear and set 2 bits mask */ 103 /* clear and set 2 bits mask */
118 if (pin > (NUM_OF_PINS / 2) - 1) { 104 if (pin > (QE_PIO_PINS / 2) - 1) {
119 out_be32(&par_io[port].cppar2, 105 out_be32(&par_io->cppar2,
120 ~pin_mask2bits & tmp_val); 106 ~pin_mask2bits & tmp_val);
121 tmp_val &= ~pin_mask2bits; 107 tmp_val &= ~pin_mask2bits;
122 out_be32(&par_io[port].cppar2, new_mask2bits | tmp_val); 108 out_be32(&par_io->cppar2, new_mask2bits | tmp_val);
123 } else { 109 } else {
124 out_be32(&par_io[port].cppar1, 110 out_be32(&par_io->cppar1,
125 ~pin_mask2bits & tmp_val); 111 ~pin_mask2bits & tmp_val);
126 tmp_val &= ~pin_mask2bits; 112 tmp_val &= ~pin_mask2bits;
127 out_be32(&par_io[port].cppar1, new_mask2bits | tmp_val); 113 out_be32(&par_io->cppar1, new_mask2bits | tmp_val);
128 } 114 }
115}
116EXPORT_SYMBOL(__par_io_config_pin);
117
118int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,
119 int assignment, int has_irq)
120{
121 if (!par_io || port >= num_par_io_ports)
122 return -EINVAL;
129 123
124 __par_io_config_pin(&par_io[port], pin, dir, open_drain, assignment,
125 has_irq);
130 return 0; 126 return 0;
131} 127}
132EXPORT_SYMBOL(par_io_config_pin); 128EXPORT_SYMBOL(par_io_config_pin);
@@ -137,10 +133,10 @@ int par_io_data_set(u8 port, u8 pin, u8 val)
137 133
138 if (port >= num_par_io_ports) 134 if (port >= num_par_io_ports)
139 return -EINVAL; 135 return -EINVAL;
140 if (pin >= NUM_OF_PINS) 136 if (pin >= QE_PIO_PINS)
141 return -EINVAL; 137 return -EINVAL;
142 /* calculate pin location */ 138 /* calculate pin location */
143 pin_mask = (u32) (1 << (NUM_OF_PINS - 1 - pin)); 139 pin_mask = (u32) (1 << (QE_PIO_PINS - 1 - pin));
144 140
145 tmp_val = in_be32(&par_io[port].cpdata); 141 tmp_val = in_be32(&par_io[port].cpdata);
146 142
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
index 0e348d9af8a6..d3c7f5af9bc8 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc.c
@@ -26,7 +26,8 @@
26#include <asm/qe.h> 26#include <asm/qe.h>
27#include <asm/ucc.h> 27#include <asm/ucc.h>
28 28
29static DEFINE_SPINLOCK(ucc_lock); 29DEFINE_SPINLOCK(cmxgcr_lock);
30EXPORT_SYMBOL(cmxgcr_lock);
30 31
31int ucc_set_qe_mux_mii_mng(unsigned int ucc_num) 32int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
32{ 33{
@@ -35,10 +36,10 @@ int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
35 if (ucc_num > UCC_MAX_NUM - 1) 36 if (ucc_num > UCC_MAX_NUM - 1)
36 return -EINVAL; 37 return -EINVAL;
37 38
38 spin_lock_irqsave(&ucc_lock, flags); 39 spin_lock_irqsave(&cmxgcr_lock, flags);
39 clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG, 40 clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG,
40 ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT); 41 ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
41 spin_unlock_irqrestore(&ucc_lock, flags); 42 spin_unlock_irqrestore(&cmxgcr_lock, flags);
42 43
43 return 0; 44 return 0;
44} 45}
diff --git a/arch/powerpc/sysdev/qe_lib/usb.c b/arch/powerpc/sysdev/qe_lib/usb.c
new file mode 100644
index 000000000000..8105462078eb
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/usb.c
@@ -0,0 +1,55 @@
1/*
2 * QE USB routines
3 *
4 * Copyright (c) Freescale Semicondutor, Inc. 2006.
5 * Shlomi Gridish <gridish@freescale.com>
6 * Jerry Huang <Chang-Ming.Huang@freescale.com>
7 * Copyright (c) MontaVista Software, Inc. 2008.
8 * Anton Vorontsov <avorontsov@ru.mvista.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/io.h>
19#include <asm/immap_qe.h>
20#include <asm/qe.h>
21
22int qe_usb_clock_set(enum qe_clock clk, int rate)
23{
24 struct qe_mux __iomem *mux = &qe_immr->qmx;
25 unsigned long flags;
26 u32 val;
27
28 switch (clk) {
29 case QE_CLK3: val = QE_CMXGCR_USBCS_CLK3; break;
30 case QE_CLK5: val = QE_CMXGCR_USBCS_CLK5; break;
31 case QE_CLK7: val = QE_CMXGCR_USBCS_CLK7; break;
32 case QE_CLK9: val = QE_CMXGCR_USBCS_CLK9; break;
33 case QE_CLK13: val = QE_CMXGCR_USBCS_CLK13; break;
34 case QE_CLK17: val = QE_CMXGCR_USBCS_CLK17; break;
35 case QE_CLK19: val = QE_CMXGCR_USBCS_CLK19; break;
36 case QE_CLK21: val = QE_CMXGCR_USBCS_CLK21; break;
37 case QE_BRG9: val = QE_CMXGCR_USBCS_BRG9; break;
38 case QE_BRG10: val = QE_CMXGCR_USBCS_BRG10; break;
39 default:
40 pr_err("%s: requested unknown clock %d\n", __func__, clk);
41 return -EINVAL;
42 }
43
44 if (qe_clock_is_brg(clk))
45 qe_setbrg(clk, rate, 1);
46
47 spin_lock_irqsave(&cmxgcr_lock, flags);
48
49 clrsetbits_be32(&mux->cmxgcr, QE_CMXGCR_USBCS, val);
50
51 spin_unlock_irqrestore(&cmxgcr_lock, flags);
52
53 return 0;
54}
55EXPORT_SYMBOL(qe_usb_clock_set);