diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-30 21:37:27 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-30 21:37:27 -0500 |
commit | 8af03e782cae1e0a0f530ddd22301cdd12cf9dc0 (patch) | |
tree | c4af13a38bd3cc1a811a37f2358491f171052070 /drivers | |
parent | 6232665040f9a23fafd9d94d4ae8d5a2dc850f65 (diff) | |
parent | 99e139126ab2e84be67969650f92eb37c12ab5cd (diff) |
Merge branch 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (454 commits)
[POWERPC] Cell IOMMU fixed mapping support
[POWERPC] Split out the ioid fetching/checking logic
[POWERPC] Add support to cell_iommu_setup_page_tables() for multiple windows
[POWERPC] Split out the IOMMU logic from cell_dma_dev_setup()
[POWERPC] Split cell_iommu_setup_hardware() into two parts
[POWERPC] Split out the logic that allocates struct iommus
[POWERPC] Allocate the hash table under 1G on cell
[POWERPC] Add set_dma_ops() to match get_dma_ops()
[POWERPC] 83xx: Clean up / convert mpc83xx board DTS files to v1 format.
[POWERPC] 85xx: Only invalidate TLB0 and TLB1
[POWERPC] 83xx: Fix typo in mpc837x compatible entries
[POWERPC] 85xx: convert sbc85* boards to use machine_device_initcall
[POWERPC] 83xx: rework platform Kconfig
[POWERPC] 85xx: rework platform Kconfig
[POWERPC] 86xx: Remove unused IRQ defines
[POWERPC] QE: Explicitly set address-cells and size cells for muram
[POWERPC] Convert StorCenter DTS file to /dts-v1/ format.
[POWERPC] 86xx: Convert all 86xx DTS files to /dts-v1/ format.
[PPC] Remove 85xx from arch/ppc
[PPC] Remove 83xx from arch/ppc
...
Diffstat (limited to 'drivers')
52 files changed, 3833 insertions, 1335 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 2478cca653de..ae19c9b30d15 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -184,7 +184,7 @@ config PATA_ACPI | |||
184 | 184 | ||
185 | config SATA_FSL | 185 | config SATA_FSL |
186 | tristate "Freescale 3.0Gbps SATA support" | 186 | tristate "Freescale 3.0Gbps SATA support" |
187 | depends on PPC_MPC837x | 187 | depends on FSL_SOC |
188 | help | 188 | help |
189 | This option enables support for Freescale 3.0Gbps SATA controller. | 189 | This option enables support for Freescale 3.0Gbps SATA controller. |
190 | It can be found on MPC837x and MPC8315. | 190 | It can be found on MPC837x and MPC8315. |
@@ -616,13 +616,23 @@ config PATA_WINBOND_VLB | |||
616 | 616 | ||
617 | config PATA_PLATFORM | 617 | config PATA_PLATFORM |
618 | tristate "Generic platform device PATA support" | 618 | tristate "Generic platform device PATA support" |
619 | depends on EMBEDDED || ARCH_RPC | 619 | depends on EMBEDDED || ARCH_RPC || PPC |
620 | help | 620 | help |
621 | This option enables support for generic directly connected ATA | 621 | This option enables support for generic directly connected ATA |
622 | devices commonly found on embedded systems. | 622 | devices commonly found on embedded systems. |
623 | 623 | ||
624 | If unsure, say N. | 624 | If unsure, say N. |
625 | 625 | ||
626 | config PATA_OF_PLATFORM | ||
627 | tristate "OpenFirmware platform device PATA support" | ||
628 | depends on PATA_PLATFORM && PPC_OF | ||
629 | help | ||
630 | This option enables support for generic directly connected ATA | ||
631 | devices commonly found on embedded systems with OpenFirmware | ||
632 | bindings. | ||
633 | |||
634 | If unsure, say N. | ||
635 | |||
626 | config PATA_ICSIDE | 636 | config PATA_ICSIDE |
627 | tristate "Acorn ICS PATA support" | 637 | tristate "Acorn ICS PATA support" |
628 | depends on ARM && ARCH_ACORN | 638 | depends on ARM && ARCH_ACORN |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 82550c16818c..701651e37c89 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -68,6 +68,7 @@ obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o | |||
68 | obj-$(CONFIG_PATA_SCC) += pata_scc.o | 68 | obj-$(CONFIG_PATA_SCC) += pata_scc.o |
69 | obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o | 69 | obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o |
70 | obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o | 70 | obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o |
71 | obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o | ||
71 | obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o | 72 | obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o |
72 | # Should be last but two libata driver | 73 | # Should be last but two libata driver |
73 | obj-$(CONFIG_PATA_ACPI) += pata_acpi.o | 74 | obj-$(CONFIG_PATA_ACPI) += pata_acpi.o |
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index dc401626cdb2..5413ebfa72e5 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c | |||
@@ -494,10 +494,8 @@ mpc52xx_ata_resume(struct of_device *op) | |||
494 | 494 | ||
495 | 495 | ||
496 | static struct of_device_id mpc52xx_ata_of_match[] = { | 496 | static struct of_device_id mpc52xx_ata_of_match[] = { |
497 | { | 497 | { .compatible = "fsl,mpc5200-ata", }, |
498 | .type = "ata", | 498 | { .compatible = "mpc5200-ata", }, |
499 | .compatible = "mpc5200-ata", | ||
500 | }, | ||
501 | {}, | 499 | {}, |
502 | }; | 500 | }; |
503 | 501 | ||
diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c new file mode 100644 index 000000000000..938f48a807eb --- /dev/null +++ b/drivers/ata/pata_of_platform.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * OF-platform PATA driver | ||
3 | * | ||
4 | * Copyright (c) 2007 MontaVista Software, Inc. | ||
5 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/of_platform.h> | ||
15 | #include <linux/pata_platform.h> | ||
16 | |||
17 | static int __devinit pata_of_platform_probe(struct of_device *ofdev, | ||
18 | const struct of_device_id *match) | ||
19 | { | ||
20 | int ret; | ||
21 | struct device_node *dn = ofdev->node; | ||
22 | struct resource io_res; | ||
23 | struct resource ctl_res; | ||
24 | struct resource irq_res; | ||
25 | unsigned int reg_shift = 0; | ||
26 | int pio_mode = 0; | ||
27 | int pio_mask; | ||
28 | const u32 *prop; | ||
29 | |||
30 | ret = of_address_to_resource(dn, 0, &io_res); | ||
31 | if (ret) { | ||
32 | dev_err(&ofdev->dev, "can't get IO address from " | ||
33 | "device tree\n"); | ||
34 | return -EINVAL; | ||
35 | } | ||
36 | |||
37 | if (of_device_is_compatible(dn, "electra-ide")) { | ||
38 | /* Altstatus is really at offset 0x3f6 from the primary window | ||
39 | * on electra-ide. Adjust ctl_res and io_res accordingly. | ||
40 | */ | ||
41 | ctl_res = io_res; | ||
42 | ctl_res.start = ctl_res.start+0x3f6; | ||
43 | io_res.end = ctl_res.start-1; | ||
44 | } else { | ||
45 | ret = of_address_to_resource(dn, 1, &ctl_res); | ||
46 | if (ret) { | ||
47 | dev_err(&ofdev->dev, "can't get CTL address from " | ||
48 | "device tree\n"); | ||
49 | return -EINVAL; | ||
50 | } | ||
51 | } | ||
52 | |||
53 | ret = of_irq_to_resource(dn, 0, &irq_res); | ||
54 | if (ret == NO_IRQ) | ||
55 | irq_res.start = irq_res.end = -1; | ||
56 | else | ||
57 | irq_res.flags = 0; | ||
58 | |||
59 | prop = of_get_property(dn, "reg-shift", NULL); | ||
60 | if (prop) | ||
61 | reg_shift = *prop; | ||
62 | |||
63 | prop = of_get_property(dn, "pio-mode", NULL); | ||
64 | if (prop) { | ||
65 | pio_mode = *prop; | ||
66 | if (pio_mode > 6) { | ||
67 | dev_err(&ofdev->dev, "invalid pio-mode\n"); | ||
68 | return -EINVAL; | ||
69 | } | ||
70 | } else { | ||
71 | dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n"); | ||
72 | } | ||
73 | |||
74 | pio_mask = 1 << pio_mode; | ||
75 | pio_mask |= (1 << pio_mode) - 1; | ||
76 | |||
77 | return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, &irq_res, | ||
78 | reg_shift, pio_mask); | ||
79 | } | ||
80 | |||
81 | static int __devexit pata_of_platform_remove(struct of_device *ofdev) | ||
82 | { | ||
83 | return __pata_platform_remove(&ofdev->dev); | ||
84 | } | ||
85 | |||
86 | static struct of_device_id pata_of_platform_match[] = { | ||
87 | { .compatible = "ata-generic", }, | ||
88 | { .compatible = "electra-ide", }, | ||
89 | {}, | ||
90 | }; | ||
91 | MODULE_DEVICE_TABLE(of, pata_of_platform_match); | ||
92 | |||
93 | static struct of_platform_driver pata_of_platform_driver = { | ||
94 | .name = "pata_of_platform", | ||
95 | .match_table = pata_of_platform_match, | ||
96 | .probe = pata_of_platform_probe, | ||
97 | .remove = __devexit_p(pata_of_platform_remove), | ||
98 | }; | ||
99 | |||
100 | static int __init pata_of_platform_init(void) | ||
101 | { | ||
102 | return of_register_platform_driver(&pata_of_platform_driver); | ||
103 | } | ||
104 | module_init(pata_of_platform_init); | ||
105 | |||
106 | static void __exit pata_of_platform_exit(void) | ||
107 | { | ||
108 | of_unregister_platform_driver(&pata_of_platform_driver); | ||
109 | } | ||
110 | module_exit(pata_of_platform_exit); | ||
111 | |||
112 | MODULE_DESCRIPTION("OF-platform PATA driver"); | ||
113 | MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>"); | ||
114 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index ac03a90a6168..224bb6c2030a 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c | |||
@@ -93,14 +93,9 @@ static struct ata_port_operations pata_platform_port_ops = { | |||
93 | }; | 93 | }; |
94 | 94 | ||
95 | static void pata_platform_setup_port(struct ata_ioports *ioaddr, | 95 | static void pata_platform_setup_port(struct ata_ioports *ioaddr, |
96 | struct pata_platform_info *info) | 96 | unsigned int shift) |
97 | { | 97 | { |
98 | unsigned int shift = 0; | ||
99 | |||
100 | /* Fixup the port shift for platforms that need it */ | 98 | /* Fixup the port shift for platforms that need it */ |
101 | if (info && info->ioport_shift) | ||
102 | shift = info->ioport_shift; | ||
103 | |||
104 | ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift); | 99 | ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift); |
105 | ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift); | 100 | ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift); |
106 | ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift); | 101 | ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift); |
@@ -114,8 +109,13 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr, | |||
114 | } | 109 | } |
115 | 110 | ||
116 | /** | 111 | /** |
117 | * pata_platform_probe - attach a platform interface | 112 | * __pata_platform_probe - attach a platform interface |
118 | * @pdev: platform device | 113 | * @dev: device |
114 | * @io_res: Resource representing I/O base | ||
115 | * @ctl_res: Resource representing CTL base | ||
116 | * @irq_res: Resource representing IRQ and its flags | ||
117 | * @ioport_shift: I/O port shift | ||
118 | * @__pio_mask: PIO mask | ||
119 | * | 119 | * |
120 | * Register a platform bus IDE interface. Such interfaces are PIO and we | 120 | * Register a platform bus IDE interface. Such interfaces are PIO and we |
121 | * assume do not support IRQ sharing. | 121 | * assume do not support IRQ sharing. |
@@ -135,42 +135,18 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr, | |||
135 | * | 135 | * |
136 | * If no IRQ resource is present, PIO polling mode is used instead. | 136 | * If no IRQ resource is present, PIO polling mode is used instead. |
137 | */ | 137 | */ |
138 | static int __devinit pata_platform_probe(struct platform_device *pdev) | 138 | int __devinit __pata_platform_probe(struct device *dev, |
139 | struct resource *io_res, | ||
140 | struct resource *ctl_res, | ||
141 | struct resource *irq_res, | ||
142 | unsigned int ioport_shift, | ||
143 | int __pio_mask) | ||
139 | { | 144 | { |
140 | struct resource *io_res, *ctl_res; | ||
141 | struct ata_host *host; | 145 | struct ata_host *host; |
142 | struct ata_port *ap; | 146 | struct ata_port *ap; |
143 | struct pata_platform_info *pp_info; | ||
144 | unsigned int mmio; | 147 | unsigned int mmio; |
145 | int irq; | 148 | int irq = 0; |
146 | 149 | int irq_flags = 0; | |
147 | /* | ||
148 | * Simple resource validation .. | ||
149 | */ | ||
150 | if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) { | ||
151 | dev_err(&pdev->dev, "invalid number of resources\n"); | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Get the I/O base first | ||
157 | */ | ||
158 | io_res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
159 | if (io_res == NULL) { | ||
160 | io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
161 | if (unlikely(io_res == NULL)) | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Then the CTL base | ||
167 | */ | ||
168 | ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1); | ||
169 | if (ctl_res == NULL) { | ||
170 | ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
171 | if (unlikely(ctl_res == NULL)) | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | 150 | ||
175 | /* | 151 | /* |
176 | * Check for MMIO | 152 | * Check for MMIO |
@@ -181,20 +157,21 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
181 | /* | 157 | /* |
182 | * And the IRQ | 158 | * And the IRQ |
183 | */ | 159 | */ |
184 | irq = platform_get_irq(pdev, 0); | 160 | if (irq_res && irq_res->start > 0) { |
185 | if (irq < 0) | 161 | irq = irq_res->start; |
186 | irq = 0; /* no irq */ | 162 | irq_flags = irq_res->flags; |
163 | } | ||
187 | 164 | ||
188 | /* | 165 | /* |
189 | * Now that that's out of the way, wire up the port.. | 166 | * Now that that's out of the way, wire up the port.. |
190 | */ | 167 | */ |
191 | host = ata_host_alloc(&pdev->dev, 1); | 168 | host = ata_host_alloc(dev, 1); |
192 | if (!host) | 169 | if (!host) |
193 | return -ENOMEM; | 170 | return -ENOMEM; |
194 | ap = host->ports[0]; | 171 | ap = host->ports[0]; |
195 | 172 | ||
196 | ap->ops = &pata_platform_port_ops; | 173 | ap->ops = &pata_platform_port_ops; |
197 | ap->pio_mask = pio_mask; | 174 | ap->pio_mask = __pio_mask; |
198 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 175 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
199 | 176 | ||
200 | /* | 177 | /* |
@@ -209,25 +186,24 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
209 | * Handle the MMIO case | 186 | * Handle the MMIO case |
210 | */ | 187 | */ |
211 | if (mmio) { | 188 | if (mmio) { |
212 | ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, io_res->start, | 189 | ap->ioaddr.cmd_addr = devm_ioremap(dev, io_res->start, |
213 | io_res->end - io_res->start + 1); | 190 | io_res->end - io_res->start + 1); |
214 | ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start, | 191 | ap->ioaddr.ctl_addr = devm_ioremap(dev, ctl_res->start, |
215 | ctl_res->end - ctl_res->start + 1); | 192 | ctl_res->end - ctl_res->start + 1); |
216 | } else { | 193 | } else { |
217 | ap->ioaddr.cmd_addr = devm_ioport_map(&pdev->dev, io_res->start, | 194 | ap->ioaddr.cmd_addr = devm_ioport_map(dev, io_res->start, |
218 | io_res->end - io_res->start + 1); | 195 | io_res->end - io_res->start + 1); |
219 | ap->ioaddr.ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start, | 196 | ap->ioaddr.ctl_addr = devm_ioport_map(dev, ctl_res->start, |
220 | ctl_res->end - ctl_res->start + 1); | 197 | ctl_res->end - ctl_res->start + 1); |
221 | } | 198 | } |
222 | if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) { | 199 | if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) { |
223 | dev_err(&pdev->dev, "failed to map IO/CTL base\n"); | 200 | dev_err(dev, "failed to map IO/CTL base\n"); |
224 | return -ENOMEM; | 201 | return -ENOMEM; |
225 | } | 202 | } |
226 | 203 | ||
227 | ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; | 204 | ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; |
228 | 205 | ||
229 | pp_info = pdev->dev.platform_data; | 206 | pata_platform_setup_port(&ap->ioaddr, ioport_shift); |
230 | pata_platform_setup_port(&ap->ioaddr, pp_info); | ||
231 | 207 | ||
232 | ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport", | 208 | ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport", |
233 | (unsigned long long)io_res->start, | 209 | (unsigned long long)io_res->start, |
@@ -235,26 +211,78 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
235 | 211 | ||
236 | /* activate */ | 212 | /* activate */ |
237 | return ata_host_activate(host, irq, irq ? ata_interrupt : NULL, | 213 | return ata_host_activate(host, irq, irq ? ata_interrupt : NULL, |
238 | pp_info ? pp_info->irq_flags : 0, | 214 | irq_flags, &pata_platform_sht); |
239 | &pata_platform_sht); | ||
240 | } | 215 | } |
216 | EXPORT_SYMBOL_GPL(__pata_platform_probe); | ||
241 | 217 | ||
242 | /** | 218 | /** |
243 | * pata_platform_remove - unplug a platform interface | 219 | * __pata_platform_remove - unplug a platform interface |
244 | * @pdev: platform device | 220 | * @dev: device |
245 | * | 221 | * |
246 | * A platform bus ATA device has been unplugged. Perform the needed | 222 | * A platform bus ATA device has been unplugged. Perform the needed |
247 | * cleanup. Also called on module unload for any active devices. | 223 | * cleanup. Also called on module unload for any active devices. |
248 | */ | 224 | */ |
249 | static int __devexit pata_platform_remove(struct platform_device *pdev) | 225 | int __devexit __pata_platform_remove(struct device *dev) |
250 | { | 226 | { |
251 | struct device *dev = &pdev->dev; | ||
252 | struct ata_host *host = dev_get_drvdata(dev); | 227 | struct ata_host *host = dev_get_drvdata(dev); |
253 | 228 | ||
254 | ata_host_detach(host); | 229 | ata_host_detach(host); |
255 | 230 | ||
256 | return 0; | 231 | return 0; |
257 | } | 232 | } |
233 | EXPORT_SYMBOL_GPL(__pata_platform_remove); | ||
234 | |||
235 | static int __devinit pata_platform_probe(struct platform_device *pdev) | ||
236 | { | ||
237 | struct resource *io_res; | ||
238 | struct resource *ctl_res; | ||
239 | struct resource *irq_res; | ||
240 | struct pata_platform_info *pp_info = pdev->dev.platform_data; | ||
241 | |||
242 | /* | ||
243 | * Simple resource validation .. | ||
244 | */ | ||
245 | if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) { | ||
246 | dev_err(&pdev->dev, "invalid number of resources\n"); | ||
247 | return -EINVAL; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * Get the I/O base first | ||
252 | */ | ||
253 | io_res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
254 | if (io_res == NULL) { | ||
255 | io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
256 | if (unlikely(io_res == NULL)) | ||
257 | return -EINVAL; | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | * Then the CTL base | ||
262 | */ | ||
263 | ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1); | ||
264 | if (ctl_res == NULL) { | ||
265 | ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
266 | if (unlikely(ctl_res == NULL)) | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * And the IRQ | ||
272 | */ | ||
273 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
274 | if (irq_res) | ||
275 | irq_res->flags = pp_info ? pp_info->irq_flags : 0; | ||
276 | |||
277 | return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res, | ||
278 | pp_info ? pp_info->ioport_shift : 0, | ||
279 | pio_mask); | ||
280 | } | ||
281 | |||
282 | static int __devexit pata_platform_remove(struct platform_device *pdev) | ||
283 | { | ||
284 | return __pata_platform_remove(&pdev->dev); | ||
285 | } | ||
258 | 286 | ||
259 | static struct platform_driver pata_platform_driver = { | 287 | static struct platform_driver pata_platform_driver = { |
260 | .probe = pata_platform_probe, | 288 | .probe = pata_platform_probe, |
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 2d7cd486e025..6bbd4fa50f3b 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -98,7 +98,7 @@ config HW_RANDOM_PASEMI | |||
98 | default HW_RANDOM | 98 | default HW_RANDOM |
99 | ---help--- | 99 | ---help--- |
100 | This driver provides kernel-side support for the Random Number | 100 | This driver provides kernel-side support for the Random Number |
101 | Generator hardware found on PA6T-1682M processor. | 101 | Generator hardware found on PA Semi PWRficient SoCs. |
102 | 102 | ||
103 | To compile this driver as a module, choose M here: the | 103 | To compile this driver as a module, choose M here: the |
104 | module will be called pasemi-rng. | 104 | module will be called pasemi-rng. |
diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index e2ea210cfa5f..6d50e9bc700b 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c | |||
@@ -134,10 +134,9 @@ static int __devexit rng_remove(struct of_device *dev) | |||
134 | } | 134 | } |
135 | 135 | ||
136 | static struct of_device_id rng_match[] = { | 136 | static struct of_device_id rng_match[] = { |
137 | { | 137 | { .compatible = "1682m-rng", }, |
138 | .compatible = "1682m-rng", | 138 | { .compatible = "pasemi,pwrficient-rng", }, |
139 | }, | 139 | { }, |
140 | {}, | ||
141 | }; | 140 | }; |
142 | 141 | ||
143 | static struct of_platform_driver rng_driver = { | 142 | static struct of_platform_driver rng_driver = { |
diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c index 9007d0677220..90320917be28 100644 --- a/drivers/edac/pasemi_edac.c +++ b/drivers/edac/pasemi_edac.c | |||
@@ -225,7 +225,7 @@ static int __devinit pasemi_edac_probe(struct pci_dev *pdev, | |||
225 | EDAC_FLAG_NONE; | 225 | EDAC_FLAG_NONE; |
226 | mci->mod_name = MODULE_NAME; | 226 | mci->mod_name = MODULE_NAME; |
227 | mci->dev_name = pci_name(pdev); | 227 | mci->dev_name = pci_name(pdev); |
228 | mci->ctl_name = "pasemi,1682m-mc"; | 228 | mci->ctl_name = "pasemi,pwrficient-mc"; |
229 | mci->edac_check = pasemi_edac_check; | 229 | mci->edac_check = pasemi_edac_check; |
230 | mci->ctl_page_to_phys = NULL; | 230 | mci->ctl_page_to_phys = NULL; |
231 | pci_read_config_dword(pdev, MCCFG_SCRUB, &scrub); | 231 | pci_read_config_dword(pdev, MCCFG_SCRUB, &scrub); |
@@ -297,4 +297,4 @@ module_exit(pasemi_edac_exit); | |||
297 | 297 | ||
298 | MODULE_LICENSE("GPL"); | 298 | MODULE_LICENSE("GPL"); |
299 | MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>"); | 299 | MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>"); |
300 | MODULE_DESCRIPTION("MC support for PA Semi PA6T-1682M memory controller"); | 300 | MODULE_DESCRIPTION("MC support for PA Semi PWRficient memory controller"); |
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index b7adde4324e4..7ce0ea64465c 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
36 | #include <linux/completion.h> | 36 | #include <linux/completion.h> |
37 | #include <linux/device.h> | 37 | #include <linux/device.h> |
38 | #include <linux/kthread.h> | ||
38 | 39 | ||
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
40 | #include <asm/semaphore.h> | 41 | #include <asm/semaphore.h> |
@@ -82,21 +83,11 @@ struct adb_driver *adb_controller; | |||
82 | BLOCKING_NOTIFIER_HEAD(adb_client_list); | 83 | BLOCKING_NOTIFIER_HEAD(adb_client_list); |
83 | static int adb_got_sleep; | 84 | static int adb_got_sleep; |
84 | static int adb_inited; | 85 | static int adb_inited; |
85 | static pid_t adb_probe_task_pid; | ||
86 | static DECLARE_MUTEX(adb_probe_mutex); | 86 | static DECLARE_MUTEX(adb_probe_mutex); |
87 | static struct completion adb_probe_task_comp; | ||
88 | static int sleepy_trackpad; | 87 | static int sleepy_trackpad; |
89 | static int autopoll_devs; | 88 | static int autopoll_devs; |
90 | int __adb_probe_sync; | 89 | int __adb_probe_sync; |
91 | 90 | ||
92 | #ifdef CONFIG_PM_SLEEP | ||
93 | static void adb_notify_sleep(struct pmu_sleep_notifier *self, int when); | ||
94 | static struct pmu_sleep_notifier adb_sleep_notifier = { | ||
95 | adb_notify_sleep, | ||
96 | SLEEP_LEVEL_ADB, | ||
97 | }; | ||
98 | #endif | ||
99 | |||
100 | static int adb_scan_bus(void); | 91 | static int adb_scan_bus(void); |
101 | static int do_adb_reset_bus(void); | 92 | static int do_adb_reset_bus(void); |
102 | static void adbdev_init(void); | 93 | static void adbdev_init(void); |
@@ -134,16 +125,6 @@ static void printADBreply(struct adb_request *req) | |||
134 | } | 125 | } |
135 | #endif | 126 | #endif |
136 | 127 | ||
137 | |||
138 | static __inline__ void adb_wait_ms(unsigned int ms) | ||
139 | { | ||
140 | if (current->pid && adb_probe_task_pid && | ||
141 | adb_probe_task_pid == current->pid) | ||
142 | msleep(ms); | ||
143 | else | ||
144 | mdelay(ms); | ||
145 | } | ||
146 | |||
147 | static int adb_scan_bus(void) | 128 | static int adb_scan_bus(void) |
148 | { | 129 | { |
149 | int i, highFree=0, noMovement; | 130 | int i, highFree=0, noMovement; |
@@ -248,13 +229,10 @@ static int adb_scan_bus(void) | |||
248 | static int | 229 | static int |
249 | adb_probe_task(void *x) | 230 | adb_probe_task(void *x) |
250 | { | 231 | { |
251 | strcpy(current->comm, "kadbprobe"); | ||
252 | |||
253 | printk(KERN_INFO "adb: starting probe task...\n"); | 232 | printk(KERN_INFO "adb: starting probe task...\n"); |
254 | do_adb_reset_bus(); | 233 | do_adb_reset_bus(); |
255 | printk(KERN_INFO "adb: finished probe task...\n"); | 234 | printk(KERN_INFO "adb: finished probe task...\n"); |
256 | 235 | ||
257 | adb_probe_task_pid = 0; | ||
258 | up(&adb_probe_mutex); | 236 | up(&adb_probe_mutex); |
259 | 237 | ||
260 | return 0; | 238 | return 0; |
@@ -263,7 +241,7 @@ adb_probe_task(void *x) | |||
263 | static void | 241 | static void |
264 | __adb_probe_task(struct work_struct *bullshit) | 242 | __adb_probe_task(struct work_struct *bullshit) |
265 | { | 243 | { |
266 | adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL); | 244 | kthread_run(adb_probe_task, NULL, "kadbprobe"); |
267 | } | 245 | } |
268 | 246 | ||
269 | static DECLARE_WORK(adb_reset_work, __adb_probe_task); | 247 | static DECLARE_WORK(adb_reset_work, __adb_probe_task); |
@@ -281,6 +259,36 @@ adb_reset_bus(void) | |||
281 | return 0; | 259 | return 0; |
282 | } | 260 | } |
283 | 261 | ||
262 | #ifdef CONFIG_PM | ||
263 | /* | ||
264 | * notify clients before sleep | ||
265 | */ | ||
266 | static int adb_suspend(struct platform_device *dev, pm_message_t state) | ||
267 | { | ||
268 | adb_got_sleep = 1; | ||
269 | /* We need to get a lock on the probe thread */ | ||
270 | down(&adb_probe_mutex); | ||
271 | /* Stop autopoll */ | ||
272 | if (adb_controller->autopoll) | ||
273 | adb_controller->autopoll(0); | ||
274 | blocking_notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * reset bus after sleep | ||
281 | */ | ||
282 | static int adb_resume(struct platform_device *dev) | ||
283 | { | ||
284 | adb_got_sleep = 0; | ||
285 | up(&adb_probe_mutex); | ||
286 | adb_reset_bus(); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | #endif /* CONFIG_PM */ | ||
291 | |||
284 | int __init adb_init(void) | 292 | int __init adb_init(void) |
285 | { | 293 | { |
286 | struct adb_driver *driver; | 294 | struct adb_driver *driver; |
@@ -313,15 +321,12 @@ int __init adb_init(void) | |||
313 | printk(KERN_WARNING "Warning: no ADB interface detected\n"); | 321 | printk(KERN_WARNING "Warning: no ADB interface detected\n"); |
314 | adb_controller = NULL; | 322 | adb_controller = NULL; |
315 | } else { | 323 | } else { |
316 | #ifdef CONFIG_PM_SLEEP | ||
317 | pmu_register_sleep_notifier(&adb_sleep_notifier); | ||
318 | #endif /* CONFIG_PM */ | ||
319 | #ifdef CONFIG_PPC | 324 | #ifdef CONFIG_PPC |
320 | if (machine_is_compatible("AAPL,PowerBook1998") || | 325 | if (machine_is_compatible("AAPL,PowerBook1998") || |
321 | machine_is_compatible("PowerBook1,1")) | 326 | machine_is_compatible("PowerBook1,1")) |
322 | sleepy_trackpad = 1; | 327 | sleepy_trackpad = 1; |
323 | #endif /* CONFIG_PPC */ | 328 | #endif /* CONFIG_PPC */ |
324 | init_completion(&adb_probe_task_comp); | 329 | |
325 | adbdev_init(); | 330 | adbdev_init(); |
326 | adb_reset_bus(); | 331 | adb_reset_bus(); |
327 | } | 332 | } |
@@ -330,33 +335,6 @@ int __init adb_init(void) | |||
330 | 335 | ||
331 | __initcall(adb_init); | 336 | __initcall(adb_init); |
332 | 337 | ||
333 | #ifdef CONFIG_PM | ||
334 | /* | ||
335 | * notify clients before sleep and reset bus afterwards | ||
336 | */ | ||
337 | void | ||
338 | adb_notify_sleep(struct pmu_sleep_notifier *self, int when) | ||
339 | { | ||
340 | switch (when) { | ||
341 | case PBOOK_SLEEP_REQUEST: | ||
342 | adb_got_sleep = 1; | ||
343 | /* We need to get a lock on the probe thread */ | ||
344 | down(&adb_probe_mutex); | ||
345 | /* Stop autopoll */ | ||
346 | if (adb_controller->autopoll) | ||
347 | adb_controller->autopoll(0); | ||
348 | blocking_notifier_call_chain(&adb_client_list, | ||
349 | ADB_MSG_POWERDOWN, NULL); | ||
350 | break; | ||
351 | case PBOOK_WAKE: | ||
352 | adb_got_sleep = 0; | ||
353 | up(&adb_probe_mutex); | ||
354 | adb_reset_bus(); | ||
355 | break; | ||
356 | } | ||
357 | } | ||
358 | #endif /* CONFIG_PM */ | ||
359 | |||
360 | static int | 338 | static int |
361 | do_adb_reset_bus(void) | 339 | do_adb_reset_bus(void) |
362 | { | 340 | { |
@@ -373,7 +351,7 @@ do_adb_reset_bus(void) | |||
373 | 351 | ||
374 | if (sleepy_trackpad) { | 352 | if (sleepy_trackpad) { |
375 | /* Let the trackpad settle down */ | 353 | /* Let the trackpad settle down */ |
376 | adb_wait_ms(500); | 354 | msleep(500); |
377 | } | 355 | } |
378 | 356 | ||
379 | down(&adb_handler_sem); | 357 | down(&adb_handler_sem); |
@@ -389,7 +367,7 @@ do_adb_reset_bus(void) | |||
389 | 367 | ||
390 | if (sleepy_trackpad) { | 368 | if (sleepy_trackpad) { |
391 | /* Let the trackpad settle down */ | 369 | /* Let the trackpad settle down */ |
392 | adb_wait_ms(1500); | 370 | msleep(1500); |
393 | } | 371 | } |
394 | 372 | ||
395 | if (!ret) { | 373 | if (!ret) { |
@@ -413,41 +391,27 @@ adb_poll(void) | |||
413 | adb_controller->poll(); | 391 | adb_controller->poll(); |
414 | } | 392 | } |
415 | 393 | ||
416 | static void | 394 | static void adb_sync_req_done(struct adb_request *req) |
417 | adb_probe_wakeup(struct adb_request *req) | ||
418 | { | 395 | { |
419 | complete(&adb_probe_task_comp); | 396 | struct completion *comp = req->arg; |
420 | } | ||
421 | 397 | ||
422 | /* Static request used during probe */ | 398 | complete(comp); |
423 | static struct adb_request adb_sreq; | 399 | } |
424 | static unsigned long adb_sreq_lock; // Use semaphore ! */ | ||
425 | 400 | ||
426 | int | 401 | int |
427 | adb_request(struct adb_request *req, void (*done)(struct adb_request *), | 402 | adb_request(struct adb_request *req, void (*done)(struct adb_request *), |
428 | int flags, int nbytes, ...) | 403 | int flags, int nbytes, ...) |
429 | { | 404 | { |
430 | va_list list; | 405 | va_list list; |
431 | int i, use_sreq; | 406 | int i; |
432 | int rc; | 407 | int rc; |
408 | struct completion comp; | ||
433 | 409 | ||
434 | if ((adb_controller == NULL) || (adb_controller->send_request == NULL)) | 410 | if ((adb_controller == NULL) || (adb_controller->send_request == NULL)) |
435 | return -ENXIO; | 411 | return -ENXIO; |
436 | if (nbytes < 1) | 412 | if (nbytes < 1) |
437 | return -EINVAL; | 413 | return -EINVAL; |
438 | if (req == NULL && (flags & ADBREQ_NOSEND)) | 414 | |
439 | return -EINVAL; | ||
440 | |||
441 | if (req == NULL) { | ||
442 | if (test_and_set_bit(0,&adb_sreq_lock)) { | ||
443 | printk("adb.c: Warning: contention on static request !\n"); | ||
444 | return -EPERM; | ||
445 | } | ||
446 | req = &adb_sreq; | ||
447 | flags |= ADBREQ_SYNC; | ||
448 | use_sreq = 1; | ||
449 | } else | ||
450 | use_sreq = 0; | ||
451 | req->nbytes = nbytes+1; | 415 | req->nbytes = nbytes+1; |
452 | req->done = done; | 416 | req->done = done; |
453 | req->reply_expected = flags & ADBREQ_REPLY; | 417 | req->reply_expected = flags & ADBREQ_REPLY; |
@@ -460,25 +424,18 @@ adb_request(struct adb_request *req, void (*done)(struct adb_request *), | |||
460 | if (flags & ADBREQ_NOSEND) | 424 | if (flags & ADBREQ_NOSEND) |
461 | return 0; | 425 | return 0; |
462 | 426 | ||
463 | /* Synchronous requests send from the probe thread cause it to | 427 | /* Synchronous requests block using an on-stack completion */ |
464 | * block. Beware that the "done" callback will be overriden ! | 428 | if (flags & ADBREQ_SYNC) { |
465 | */ | 429 | WARN_ON(done); |
466 | if ((flags & ADBREQ_SYNC) && | 430 | req->done = adb_sync_req_done; |
467 | (current->pid && adb_probe_task_pid && | 431 | req->arg = ∁ |
468 | adb_probe_task_pid == current->pid)) { | 432 | init_completion(&comp); |
469 | req->done = adb_probe_wakeup; | ||
470 | rc = adb_controller->send_request(req, 0); | ||
471 | if (rc || req->complete) | ||
472 | goto bail; | ||
473 | wait_for_completion(&adb_probe_task_comp); | ||
474 | rc = 0; | ||
475 | goto bail; | ||
476 | } | 433 | } |
477 | 434 | ||
478 | rc = adb_controller->send_request(req, flags & ADBREQ_SYNC); | 435 | rc = adb_controller->send_request(req, 0); |
479 | bail: | 436 | |
480 | if (use_sreq) | 437 | if ((flags & ADBREQ_SYNC) && !rc && !req->complete) |
481 | clear_bit(0, &adb_sreq_lock); | 438 | wait_for_completion(&comp); |
482 | 439 | ||
483 | return rc; | 440 | return rc; |
484 | } | 441 | } |
@@ -864,7 +821,29 @@ static const struct file_operations adb_fops = { | |||
864 | .release = adb_release, | 821 | .release = adb_release, |
865 | }; | 822 | }; |
866 | 823 | ||
867 | static void | 824 | static struct platform_driver adb_pfdrv = { |
825 | .driver = { | ||
826 | .name = "adb", | ||
827 | }, | ||
828 | #ifdef CONFIG_PM | ||
829 | .suspend = adb_suspend, | ||
830 | .resume = adb_resume, | ||
831 | #endif | ||
832 | }; | ||
833 | |||
834 | static struct platform_device adb_pfdev = { | ||
835 | .name = "adb", | ||
836 | }; | ||
837 | |||
838 | static int __init | ||
839 | adb_dummy_probe(struct platform_device *dev) | ||
840 | { | ||
841 | if (dev == &adb_pfdev) | ||
842 | return 0; | ||
843 | return -ENODEV; | ||
844 | } | ||
845 | |||
846 | static void __init | ||
868 | adbdev_init(void) | 847 | adbdev_init(void) |
869 | { | 848 | { |
870 | if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) { | 849 | if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) { |
@@ -876,4 +855,7 @@ adbdev_init(void) | |||
876 | if (IS_ERR(adb_dev_class)) | 855 | if (IS_ERR(adb_dev_class)) |
877 | return; | 856 | return; |
878 | device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), "adb"); | 857 | device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), "adb"); |
858 | |||
859 | platform_device_register(&adb_pfdev); | ||
860 | platform_driver_probe(&adb_pfdrv, adb_dummy_probe); | ||
879 | } | 861 | } |
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index eaba4a9b231e..18dde2a27209 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/stddef.h> | 20 | #include <linux/stddef.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/ide.h> | 22 | #include <linux/ide.h> |
23 | #include <linux/kthread.h> | ||
23 | #include <asm/prom.h> | 24 | #include <asm/prom.h> |
24 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
@@ -35,7 +36,6 @@ | |||
35 | 36 | ||
36 | 37 | ||
37 | #define MB_DEBUG | 38 | #define MB_DEBUG |
38 | #define MB_IGNORE_SIGNALS | ||
39 | 39 | ||
40 | #ifdef MB_DEBUG | 40 | #ifdef MB_DEBUG |
41 | #define MBDBG(fmt, arg...) printk(KERN_INFO fmt , ## arg) | 41 | #define MBDBG(fmt, arg...) printk(KERN_INFO fmt , ## arg) |
@@ -623,12 +623,7 @@ static int media_bay_task(void *x) | |||
623 | { | 623 | { |
624 | int i; | 624 | int i; |
625 | 625 | ||
626 | strcpy(current->comm, "media-bay"); | 626 | while (!kthread_should_stop()) { |
627 | #ifdef MB_IGNORE_SIGNALS | ||
628 | sigfillset(¤t->blocked); | ||
629 | #endif | ||
630 | |||
631 | for (;;) { | ||
632 | for (i = 0; i < media_bay_count; ++i) { | 627 | for (i = 0; i < media_bay_count; ++i) { |
633 | down(&media_bays[i].lock); | 628 | down(&media_bays[i].lock); |
634 | if (!media_bays[i].sleeping) | 629 | if (!media_bays[i].sleeping) |
@@ -637,9 +632,8 @@ static int media_bay_task(void *x) | |||
637 | } | 632 | } |
638 | 633 | ||
639 | msleep_interruptible(MB_POLL_DELAY); | 634 | msleep_interruptible(MB_POLL_DELAY); |
640 | if (signal_pending(current)) | ||
641 | return 0; | ||
642 | } | 635 | } |
636 | return 0; | ||
643 | } | 637 | } |
644 | 638 | ||
645 | static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match) | 639 | static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match) |
@@ -700,7 +694,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de | |||
700 | 694 | ||
701 | /* Startup kernel thread */ | 695 | /* Startup kernel thread */ |
702 | if (i == 0) | 696 | if (i == 0) |
703 | kernel_thread(media_bay_task, NULL, CLONE_KERNEL); | 697 | kthread_run(media_bay_task, NULL, "media-bay"); |
704 | 698 | ||
705 | return 0; | 699 | return 0; |
706 | 700 | ||
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 276945d51513..54f4942a2968 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -553,6 +553,7 @@ thermostat_init(void) | |||
553 | struct device_node* np; | 553 | struct device_node* np; |
554 | const u32 *prop; | 554 | const u32 *prop; |
555 | int i = 0, offset = 0; | 555 | int i = 0, offset = 0; |
556 | int err; | ||
556 | 557 | ||
557 | np = of_find_node_by_name(NULL, "fan"); | 558 | np = of_find_node_by_name(NULL, "fan"); |
558 | if (!np) | 559 | if (!np) |
@@ -612,17 +613,20 @@ thermostat_init(void) | |||
612 | return -ENODEV; | 613 | return -ENODEV; |
613 | } | 614 | } |
614 | 615 | ||
615 | device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); | 616 | err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); |
616 | device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); | 617 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); |
617 | device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); | 618 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); |
618 | device_create_file(&of_dev->dev, &dev_attr_sensor2_limit); | 619 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_limit); |
619 | device_create_file(&of_dev->dev, &dev_attr_sensor1_location); | 620 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_location); |
620 | device_create_file(&of_dev->dev, &dev_attr_sensor2_location); | 621 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_location); |
621 | device_create_file(&of_dev->dev, &dev_attr_limit_adjust); | 622 | err |= device_create_file(&of_dev->dev, &dev_attr_limit_adjust); |
622 | device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed); | 623 | err |= device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed); |
623 | device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); | 624 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); |
624 | if(therm_type == ADT7460) | 625 | if(therm_type == ADT7460) |
625 | device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); | 626 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); |
627 | if (err) | ||
628 | printk(KERN_WARNING | ||
629 | "Failed to create tempertaure attribute file(s).\n"); | ||
626 | 630 | ||
627 | #ifndef CONFIG_I2C_POWERMAC | 631 | #ifndef CONFIG_I2C_POWERMAC |
628 | request_module("i2c-powermac"); | 632 | request_module("i2c-powermac"); |
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index e43554e754a4..1e0a69a5e815 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -121,6 +121,7 @@ | |||
121 | #include <linux/reboot.h> | 121 | #include <linux/reboot.h> |
122 | #include <linux/kmod.h> | 122 | #include <linux/kmod.h> |
123 | #include <linux/i2c.h> | 123 | #include <linux/i2c.h> |
124 | #include <linux/kthread.h> | ||
124 | #include <asm/prom.h> | 125 | #include <asm/prom.h> |
125 | #include <asm/machdep.h> | 126 | #include <asm/machdep.h> |
126 | #include <asm/io.h> | 127 | #include <asm/io.h> |
@@ -161,7 +162,7 @@ static struct slots_pid_state slots_state; | |||
161 | static int state; | 162 | static int state; |
162 | static int cpu_count; | 163 | static int cpu_count; |
163 | static int cpu_pid_type; | 164 | static int cpu_pid_type; |
164 | static pid_t ctrl_task; | 165 | static struct task_struct *ctrl_task; |
165 | static struct completion ctrl_complete; | 166 | static struct completion ctrl_complete; |
166 | static int critical_state; | 167 | static int critical_state; |
167 | static int rackmac; | 168 | static int rackmac; |
@@ -1156,6 +1157,8 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state) | |||
1156 | */ | 1157 | */ |
1157 | static int init_cpu_state(struct cpu_pid_state *state, int index) | 1158 | static int init_cpu_state(struct cpu_pid_state *state, int index) |
1158 | { | 1159 | { |
1160 | int err; | ||
1161 | |||
1159 | state->index = index; | 1162 | state->index = index; |
1160 | state->first = 1; | 1163 | state->first = 1; |
1161 | state->rpm = (cpu_pid_type == CPU_PID_TYPE_RACKMAC) ? 4000 : 1000; | 1164 | state->rpm = (cpu_pid_type == CPU_PID_TYPE_RACKMAC) ? 4000 : 1000; |
@@ -1181,18 +1184,21 @@ static int init_cpu_state(struct cpu_pid_state *state, int index) | |||
1181 | DBG("CPU %d Using %d power history entries\n", index, state->count_power); | 1184 | DBG("CPU %d Using %d power history entries\n", index, state->count_power); |
1182 | 1185 | ||
1183 | if (index == 0) { | 1186 | if (index == 0) { |
1184 | device_create_file(&of_dev->dev, &dev_attr_cpu0_temperature); | 1187 | err = device_create_file(&of_dev->dev, &dev_attr_cpu0_temperature); |
1185 | device_create_file(&of_dev->dev, &dev_attr_cpu0_voltage); | 1188 | err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_voltage); |
1186 | device_create_file(&of_dev->dev, &dev_attr_cpu0_current); | 1189 | err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_current); |
1187 | device_create_file(&of_dev->dev, &dev_attr_cpu0_exhaust_fan_rpm); | 1190 | err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_exhaust_fan_rpm); |
1188 | device_create_file(&of_dev->dev, &dev_attr_cpu0_intake_fan_rpm); | 1191 | err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_intake_fan_rpm); |
1189 | } else { | 1192 | } else { |
1190 | device_create_file(&of_dev->dev, &dev_attr_cpu1_temperature); | 1193 | err = device_create_file(&of_dev->dev, &dev_attr_cpu1_temperature); |
1191 | device_create_file(&of_dev->dev, &dev_attr_cpu1_voltage); | 1194 | err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_voltage); |
1192 | device_create_file(&of_dev->dev, &dev_attr_cpu1_current); | 1195 | err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_current); |
1193 | device_create_file(&of_dev->dev, &dev_attr_cpu1_exhaust_fan_rpm); | 1196 | err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_exhaust_fan_rpm); |
1194 | device_create_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); | 1197 | err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); |
1195 | } | 1198 | } |
1199 | if (err) | ||
1200 | printk(KERN_WARNING "Failed to create some of the atribute" | ||
1201 | "files for CPU %d\n", index); | ||
1196 | 1202 | ||
1197 | return 0; | 1203 | return 0; |
1198 | fail: | 1204 | fail: |
@@ -1328,6 +1334,7 @@ static int init_backside_state(struct backside_pid_state *state) | |||
1328 | { | 1334 | { |
1329 | struct device_node *u3; | 1335 | struct device_node *u3; |
1330 | int u3h = 1; /* conservative by default */ | 1336 | int u3h = 1; /* conservative by default */ |
1337 | int err; | ||
1331 | 1338 | ||
1332 | /* | 1339 | /* |
1333 | * There are different PID params for machines with U3 and machines | 1340 | * There are different PID params for machines with U3 and machines |
@@ -1379,8 +1386,11 @@ static int init_backside_state(struct backside_pid_state *state) | |||
1379 | if (state->monitor == NULL) | 1386 | if (state->monitor == NULL) |
1380 | return -ENODEV; | 1387 | return -ENODEV; |
1381 | 1388 | ||
1382 | device_create_file(&of_dev->dev, &dev_attr_backside_temperature); | 1389 | err = device_create_file(&of_dev->dev, &dev_attr_backside_temperature); |
1383 | device_create_file(&of_dev->dev, &dev_attr_backside_fan_pwm); | 1390 | err |= device_create_file(&of_dev->dev, &dev_attr_backside_fan_pwm); |
1391 | if (err) | ||
1392 | printk(KERN_WARNING "Failed to create attribute file(s)" | ||
1393 | " for backside fan\n"); | ||
1384 | 1394 | ||
1385 | return 0; | 1395 | return 0; |
1386 | } | 1396 | } |
@@ -1491,6 +1501,8 @@ static void do_monitor_drives(struct drives_pid_state *state) | |||
1491 | */ | 1501 | */ |
1492 | static int init_drives_state(struct drives_pid_state *state) | 1502 | static int init_drives_state(struct drives_pid_state *state) |
1493 | { | 1503 | { |
1504 | int err; | ||
1505 | |||
1494 | state->ticks = 1; | 1506 | state->ticks = 1; |
1495 | state->first = 1; | 1507 | state->first = 1; |
1496 | state->rpm = 1000; | 1508 | state->rpm = 1000; |
@@ -1499,8 +1511,11 @@ static int init_drives_state(struct drives_pid_state *state) | |||
1499 | if (state->monitor == NULL) | 1511 | if (state->monitor == NULL) |
1500 | return -ENODEV; | 1512 | return -ENODEV; |
1501 | 1513 | ||
1502 | device_create_file(&of_dev->dev, &dev_attr_drives_temperature); | 1514 | err = device_create_file(&of_dev->dev, &dev_attr_drives_temperature); |
1503 | device_create_file(&of_dev->dev, &dev_attr_drives_fan_rpm); | 1515 | err |= device_create_file(&of_dev->dev, &dev_attr_drives_fan_rpm); |
1516 | if (err) | ||
1517 | printk(KERN_WARNING "Failed to create attribute file(s)" | ||
1518 | " for drives bay fan\n"); | ||
1504 | 1519 | ||
1505 | return 0; | 1520 | return 0; |
1506 | } | 1521 | } |
@@ -1621,7 +1636,9 @@ static int init_dimms_state(struct dimm_pid_state *state) | |||
1621 | if (state->monitor == NULL) | 1636 | if (state->monitor == NULL) |
1622 | return -ENODEV; | 1637 | return -ENODEV; |
1623 | 1638 | ||
1624 | device_create_file(&of_dev->dev, &dev_attr_dimms_temperature); | 1639 | if (device_create_file(&of_dev->dev, &dev_attr_dimms_temperature)) |
1640 | printk(KERN_WARNING "Failed to create attribute file" | ||
1641 | " for DIMM temperature\n"); | ||
1625 | 1642 | ||
1626 | return 0; | 1643 | return 0; |
1627 | } | 1644 | } |
@@ -1731,6 +1748,8 @@ static void do_monitor_slots(struct slots_pid_state *state) | |||
1731 | */ | 1748 | */ |
1732 | static int init_slots_state(struct slots_pid_state *state) | 1749 | static int init_slots_state(struct slots_pid_state *state) |
1733 | { | 1750 | { |
1751 | int err; | ||
1752 | |||
1734 | state->ticks = 1; | 1753 | state->ticks = 1; |
1735 | state->first = 1; | 1754 | state->first = 1; |
1736 | state->pwm = 50; | 1755 | state->pwm = 50; |
@@ -1739,8 +1758,11 @@ static int init_slots_state(struct slots_pid_state *state) | |||
1739 | if (state->monitor == NULL) | 1758 | if (state->monitor == NULL) |
1740 | return -ENODEV; | 1759 | return -ENODEV; |
1741 | 1760 | ||
1742 | device_create_file(&of_dev->dev, &dev_attr_slots_temperature); | 1761 | err = device_create_file(&of_dev->dev, &dev_attr_slots_temperature); |
1743 | device_create_file(&of_dev->dev, &dev_attr_slots_fan_pwm); | 1762 | err |= device_create_file(&of_dev->dev, &dev_attr_slots_fan_pwm); |
1763 | if (err) | ||
1764 | printk(KERN_WARNING "Failed to create attribute file(s)" | ||
1765 | " for slots bay fan\n"); | ||
1744 | 1766 | ||
1745 | return 0; | 1767 | return 0; |
1746 | } | 1768 | } |
@@ -1779,8 +1801,6 @@ static int call_critical_overtemp(void) | |||
1779 | */ | 1801 | */ |
1780 | static int main_control_loop(void *x) | 1802 | static int main_control_loop(void *x) |
1781 | { | 1803 | { |
1782 | daemonize("kfand"); | ||
1783 | |||
1784 | DBG("main_control_loop started\n"); | 1804 | DBG("main_control_loop started\n"); |
1785 | 1805 | ||
1786 | down(&driver_lock); | 1806 | down(&driver_lock); |
@@ -1956,7 +1976,7 @@ static void start_control_loops(void) | |||
1956 | { | 1976 | { |
1957 | init_completion(&ctrl_complete); | 1977 | init_completion(&ctrl_complete); |
1958 | 1978 | ||
1959 | ctrl_task = kernel_thread(main_control_loop, NULL, SIGCHLD | CLONE_KERNEL); | 1979 | ctrl_task = kthread_run(main_control_loop, NULL, "kfand"); |
1960 | } | 1980 | } |
1961 | 1981 | ||
1962 | /* | 1982 | /* |
@@ -1964,7 +1984,7 @@ static void start_control_loops(void) | |||
1964 | */ | 1984 | */ |
1965 | static void stop_control_loops(void) | 1985 | static void stop_control_loops(void) |
1966 | { | 1986 | { |
1967 | if (ctrl_task != 0) | 1987 | if (ctrl_task) |
1968 | wait_for_completion(&ctrl_complete); | 1988 | wait_for_completion(&ctrl_complete); |
1969 | } | 1989 | } |
1970 | 1990 | ||
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index b66da74caa55..d11821af3b8d 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/i2c.h> | 36 | #include <linux/i2c.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/kthread.h> | ||
39 | 40 | ||
40 | #include <asm/prom.h> | 41 | #include <asm/prom.h> |
41 | #include <asm/machdep.h> | 42 | #include <asm/machdep.h> |
@@ -59,8 +60,7 @@ I2C_CLIENT_INSMOD; | |||
59 | 60 | ||
60 | static struct { | 61 | static struct { |
61 | volatile int running; | 62 | volatile int running; |
62 | struct completion completion; | 63 | struct task_struct *poll_task; |
63 | pid_t poll_task; | ||
64 | 64 | ||
65 | struct semaphore lock; | 65 | struct semaphore lock; |
66 | struct of_device *of_dev; | 66 | struct of_device *of_dev; |
@@ -221,6 +221,7 @@ static void | |||
221 | setup_hardware( void ) | 221 | setup_hardware( void ) |
222 | { | 222 | { |
223 | int val; | 223 | int val; |
224 | int err; | ||
224 | 225 | ||
225 | /* save registers (if we unload the module) */ | 226 | /* save registers (if we unload the module) */ |
226 | x.r0 = read_reg( x.fan, 0x00, 1 ); | 227 | x.r0 = read_reg( x.fan, 0x00, 1 ); |
@@ -263,8 +264,11 @@ setup_hardware( void ) | |||
263 | x.upind = -1; | 264 | x.upind = -1; |
264 | /* tune_fan( fan_up_table[x.upind].fan_setting ); */ | 265 | /* tune_fan( fan_up_table[x.upind].fan_setting ); */ |
265 | 266 | ||
266 | device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature ); | 267 | err = device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature ); |
267 | device_create_file( &x.of_dev->dev, &dev_attr_case_temperature ); | 268 | err |= device_create_file( &x.of_dev->dev, &dev_attr_case_temperature ); |
269 | if (err) | ||
270 | printk(KERN_WARNING | ||
271 | "Failed to create temperature attribute file(s).\n"); | ||
268 | } | 272 | } |
269 | 273 | ||
270 | static void | 274 | static void |
@@ -280,27 +284,27 @@ restore_regs( void ) | |||
280 | write_reg( x.fan, 0x00, x.r0, 1 ); | 284 | write_reg( x.fan, 0x00, x.r0, 1 ); |
281 | } | 285 | } |
282 | 286 | ||
283 | static int | 287 | static int control_loop(void *dummy) |
284 | control_loop( void *dummy ) | ||
285 | { | 288 | { |
286 | daemonize("g4fand"); | 289 | down(&x.lock); |
287 | |||
288 | down( &x.lock ); | ||
289 | setup_hardware(); | 290 | setup_hardware(); |
291 | up(&x.lock); | ||
290 | 292 | ||
291 | while( x.running ) { | 293 | for (;;) { |
292 | up( &x.lock ); | ||
293 | |||
294 | msleep_interruptible(8000); | 294 | msleep_interruptible(8000); |
295 | 295 | if (kthread_should_stop()) | |
296 | down( &x.lock ); | 296 | break; |
297 | |||
298 | down(&x.lock); | ||
297 | poll_temp(); | 299 | poll_temp(); |
300 | up(&x.lock); | ||
298 | } | 301 | } |
299 | 302 | ||
303 | down(&x.lock); | ||
300 | restore_regs(); | 304 | restore_regs(); |
301 | up( &x.lock ); | 305 | up(&x.lock); |
302 | 306 | ||
303 | complete_and_exit( &x.completion, 0 ); | 307 | return 0; |
304 | } | 308 | } |
305 | 309 | ||
306 | 310 | ||
@@ -320,8 +324,7 @@ do_attach( struct i2c_adapter *adapter ) | |||
320 | ret = i2c_probe( adapter, &addr_data, &do_probe ); | 324 | ret = i2c_probe( adapter, &addr_data, &do_probe ); |
321 | if( x.thermostat && x.fan ) { | 325 | if( x.thermostat && x.fan ) { |
322 | x.running = 1; | 326 | x.running = 1; |
323 | init_completion( &x.completion ); | 327 | x.poll_task = kthread_run(control_loop, NULL, "g4fand"); |
324 | x.poll_task = kernel_thread( control_loop, NULL, SIGCHLD | CLONE_KERNEL ); | ||
325 | } | 328 | } |
326 | } | 329 | } |
327 | return ret; | 330 | return ret; |
@@ -337,7 +340,8 @@ do_detach( struct i2c_client *client ) | |||
337 | else { | 340 | else { |
338 | if( x.running ) { | 341 | if( x.running ) { |
339 | x.running = 0; | 342 | x.running = 0; |
340 | wait_for_completion( &x.completion ); | 343 | kthread_stop(x.poll_task); |
344 | x.poll_task = NULL; | ||
341 | } | 345 | } |
342 | if( client == x.thermostat ) | 346 | if( client == x.thermostat ) |
343 | x.thermostat = NULL; | 347 | x.thermostat = NULL; |
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index 7e27071746e4..741a2e3f4fc6 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c | |||
@@ -22,7 +22,7 @@ static u8 bl_curve[FB_BACKLIGHT_LEVELS]; | |||
22 | 22 | ||
23 | static void pmu_backlight_init_curve(u8 off, u8 min, u8 max) | 23 | static void pmu_backlight_init_curve(u8 off, u8 min, u8 max) |
24 | { | 24 | { |
25 | unsigned int i, flat, count, range = (max - min); | 25 | int i, flat, count, range = (max - min); |
26 | 26 | ||
27 | bl_curve[0] = off; | 27 | bl_curve[0] = off; |
28 | 28 | ||
@@ -68,17 +68,11 @@ static int pmu_backlight_get_level_brightness(int level) | |||
68 | return pmulevel; | 68 | return pmulevel; |
69 | } | 69 | } |
70 | 70 | ||
71 | static int pmu_backlight_update_status(struct backlight_device *bd) | 71 | static int __pmu_backlight_update_status(struct backlight_device *bd) |
72 | { | 72 | { |
73 | struct adb_request req; | 73 | struct adb_request req; |
74 | unsigned long flags; | ||
75 | int level = bd->props.brightness; | 74 | int level = bd->props.brightness; |
76 | 75 | ||
77 | spin_lock_irqsave(&pmu_backlight_lock, flags); | ||
78 | |||
79 | /* Don't update brightness when sleeping */ | ||
80 | if (sleeping) | ||
81 | goto out; | ||
82 | 76 | ||
83 | if (bd->props.power != FB_BLANK_UNBLANK || | 77 | if (bd->props.power != FB_BLANK_UNBLANK || |
84 | bd->props.fb_blank != FB_BLANK_UNBLANK) | 78 | bd->props.fb_blank != FB_BLANK_UNBLANK) |
@@ -99,12 +93,23 @@ static int pmu_backlight_update_status(struct backlight_device *bd) | |||
99 | pmu_wait_complete(&req); | 93 | pmu_wait_complete(&req); |
100 | } | 94 | } |
101 | 95 | ||
102 | out: | ||
103 | spin_unlock_irqrestore(&pmu_backlight_lock, flags); | ||
104 | |||
105 | return 0; | 96 | return 0; |
106 | } | 97 | } |
107 | 98 | ||
99 | static int pmu_backlight_update_status(struct backlight_device *bd) | ||
100 | { | ||
101 | unsigned long flags; | ||
102 | int rc = 0; | ||
103 | |||
104 | spin_lock_irqsave(&pmu_backlight_lock, flags); | ||
105 | /* Don't update brightness when sleeping */ | ||
106 | if (!sleeping) | ||
107 | rc = __pmu_backlight_update_status(bd); | ||
108 | spin_unlock_irqrestore(&pmu_backlight_lock, flags); | ||
109 | return rc; | ||
110 | } | ||
111 | |||
112 | |||
108 | static int pmu_backlight_get_brightness(struct backlight_device *bd) | 113 | static int pmu_backlight_get_brightness(struct backlight_device *bd) |
109 | { | 114 | { |
110 | return bd->props.brightness; | 115 | return bd->props.brightness; |
@@ -123,6 +128,16 @@ void pmu_backlight_set_sleep(int sleep) | |||
123 | 128 | ||
124 | spin_lock_irqsave(&pmu_backlight_lock, flags); | 129 | spin_lock_irqsave(&pmu_backlight_lock, flags); |
125 | sleeping = sleep; | 130 | sleeping = sleep; |
131 | if (pmac_backlight) { | ||
132 | if (sleep) { | ||
133 | struct adb_request req; | ||
134 | |||
135 | pmu_request(&req, NULL, 2, PMU_POWER_CTRL, | ||
136 | PMU_POW_BACKLIGHT | PMU_POW_OFF); | ||
137 | pmu_wait_complete(&req); | ||
138 | } else | ||
139 | __pmu_backlight_update_status(pmac_backlight); | ||
140 | } | ||
126 | spin_unlock_irqrestore(&pmu_backlight_lock, flags); | 141 | spin_unlock_irqrestore(&pmu_backlight_lock, flags); |
127 | } | 142 | } |
128 | #endif /* CONFIG_PM */ | 143 | #endif /* CONFIG_PM */ |
@@ -148,8 +163,8 @@ void __init pmu_backlight_init() | |||
148 | 163 | ||
149 | bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data); | 164 | bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data); |
150 | if (IS_ERR(bd)) { | 165 | if (IS_ERR(bd)) { |
151 | printk("pmubl: Backlight registration failed\n"); | 166 | printk(KERN_ERR "PMU Backlight registration failed\n"); |
152 | goto error; | 167 | return; |
153 | } | 168 | } |
154 | bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | 169 | bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; |
155 | pmu_backlight_init_curve(0x7F, 0x46, 0x0E); | 170 | pmu_backlight_init_curve(0x7F, 0x46, 0x0E); |
@@ -171,10 +186,5 @@ void __init pmu_backlight_init() | |||
171 | bd->props.power = FB_BLANK_UNBLANK; | 186 | bd->props.power = FB_BLANK_UNBLANK; |
172 | backlight_update_status(bd); | 187 | backlight_update_status(bd); |
173 | 188 | ||
174 | printk("pmubl: Backlight initialized (%s)\n", name); | 189 | printk(KERN_INFO "PMU Backlight initialized (%s)\n", name); |
175 | |||
176 | return; | ||
177 | |||
178 | error: | ||
179 | return; | ||
180 | } | 190 | } |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index ac420b17e16f..ebec663d5d37 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -10,13 +10,11 @@ | |||
10 | * | 10 | * |
11 | * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi. | 11 | * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi. |
12 | * Copyright (C) 2001-2002 Benjamin Herrenschmidt | 12 | * Copyright (C) 2001-2002 Benjamin Herrenschmidt |
13 | * Copyright (C) 2006-2007 Johannes Berg | ||
13 | * | 14 | * |
14 | * THIS DRIVER IS BECOMING A TOTAL MESS ! | 15 | * THIS DRIVER IS BECOMING A TOTAL MESS ! |
15 | * - Cleanup atomically disabling reply to PMU events after | 16 | * - Cleanup atomically disabling reply to PMU events after |
16 | * a sleep or a freq. switch | 17 | * a sleep or a freq. switch |
17 | * - Move sleep code out of here to pmac_pm, merge into new | ||
18 | * common PM infrastructure | ||
19 | * - Save/Restore PCI space properly | ||
20 | * | 18 | * |
21 | */ | 19 | */ |
22 | #include <stdarg.h> | 20 | #include <stdarg.h> |
@@ -33,7 +31,6 @@ | |||
33 | #include <linux/adb.h> | 31 | #include <linux/adb.h> |
34 | #include <linux/pmu.h> | 32 | #include <linux/pmu.h> |
35 | #include <linux/cuda.h> | 33 | #include <linux/cuda.h> |
36 | #include <linux/smp_lock.h> | ||
37 | #include <linux/module.h> | 34 | #include <linux/module.h> |
38 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
39 | #include <linux/pm.h> | 36 | #include <linux/pm.h> |
@@ -65,9 +62,7 @@ | |||
65 | #include "via-pmu-event.h" | 62 | #include "via-pmu-event.h" |
66 | 63 | ||
67 | /* Some compile options */ | 64 | /* Some compile options */ |
68 | #undef SUSPEND_USES_PMU | 65 | #undef DEBUG_SLEEP |
69 | #define DEBUG_SLEEP | ||
70 | #undef HACKED_PCI_SAVE | ||
71 | 66 | ||
72 | /* Misc minor number allocated for /dev/pmu */ | 67 | /* Misc minor number allocated for /dev/pmu */ |
73 | #define PMU_MINOR 154 | 68 | #define PMU_MINOR 154 |
@@ -152,12 +147,9 @@ static spinlock_t pmu_lock; | |||
152 | static u8 pmu_intr_mask; | 147 | static u8 pmu_intr_mask; |
153 | static int pmu_version; | 148 | static int pmu_version; |
154 | static int drop_interrupts; | 149 | static int drop_interrupts; |
155 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) | 150 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) |
156 | static int option_lid_wakeup = 1; | 151 | static int option_lid_wakeup = 1; |
157 | #endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ | 152 | #endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ |
158 | #if (defined(CONFIG_PM_SLEEP)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY) | ||
159 | static int sleep_in_progress; | ||
160 | #endif | ||
161 | static unsigned long async_req_locks; | 153 | static unsigned long async_req_locks; |
162 | static unsigned int pmu_irq_stats[11]; | 154 | static unsigned int pmu_irq_stats[11]; |
163 | 155 | ||
@@ -177,7 +169,6 @@ static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES]; | |||
177 | 169 | ||
178 | int __fake_sleep; | 170 | int __fake_sleep; |
179 | int asleep; | 171 | int asleep; |
180 | BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); | ||
181 | 172 | ||
182 | #ifdef CONFIG_ADB | 173 | #ifdef CONFIG_ADB |
183 | static int adb_dev_map; | 174 | static int adb_dev_map; |
@@ -224,7 +215,7 @@ extern void enable_kernel_fp(void); | |||
224 | 215 | ||
225 | #ifdef DEBUG_SLEEP | 216 | #ifdef DEBUG_SLEEP |
226 | int pmu_polled_request(struct adb_request *req); | 217 | int pmu_polled_request(struct adb_request *req); |
227 | int pmu_wink(struct adb_request *req); | 218 | void pmu_blink(int n); |
228 | #endif | 219 | #endif |
229 | 220 | ||
230 | /* | 221 | /* |
@@ -875,7 +866,7 @@ proc_read_options(char *page, char **start, off_t off, | |||
875 | { | 866 | { |
876 | char *p = page; | 867 | char *p = page; |
877 | 868 | ||
878 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) | 869 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) |
879 | if (pmu_kind == PMU_KEYLARGO_BASED && | 870 | if (pmu_kind == PMU_KEYLARGO_BASED && |
880 | pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) | 871 | pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) |
881 | p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup); | 872 | p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup); |
@@ -916,7 +907,7 @@ proc_write_options(struct file *file, const char __user *buffer, | |||
916 | *(val++) = 0; | 907 | *(val++) = 0; |
917 | while(*val == ' ') | 908 | while(*val == ' ') |
918 | val++; | 909 | val++; |
919 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) | 910 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) |
920 | if (pmu_kind == PMU_KEYLARGO_BASED && | 911 | if (pmu_kind == PMU_KEYLARGO_BASED && |
921 | pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) | 912 | pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) |
922 | if (!strcmp(label, "lid_wakeup")) | 913 | if (!strcmp(label, "lid_wakeup")) |
@@ -1256,9 +1247,7 @@ void | |||
1256 | pmu_suspend(void) | 1247 | pmu_suspend(void) |
1257 | { | 1248 | { |
1258 | unsigned long flags; | 1249 | unsigned long flags; |
1259 | #ifdef SUSPEND_USES_PMU | 1250 | |
1260 | struct adb_request *req; | ||
1261 | #endif | ||
1262 | if (!via) | 1251 | if (!via) |
1263 | return; | 1252 | return; |
1264 | 1253 | ||
@@ -1276,17 +1265,10 @@ pmu_suspend(void) | |||
1276 | via_pmu_interrupt(0, NULL); | 1265 | via_pmu_interrupt(0, NULL); |
1277 | spin_lock_irqsave(&pmu_lock, flags); | 1266 | spin_lock_irqsave(&pmu_lock, flags); |
1278 | if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) { | 1267 | if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) { |
1279 | #ifdef SUSPEND_USES_PMU | ||
1280 | pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0); | ||
1281 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
1282 | while(!req.complete) | ||
1283 | pmu_poll(); | ||
1284 | #else /* SUSPEND_USES_PMU */ | ||
1285 | if (gpio_irq >= 0) | 1268 | if (gpio_irq >= 0) |
1286 | disable_irq_nosync(gpio_irq); | 1269 | disable_irq_nosync(gpio_irq); |
1287 | out_8(&via[IER], CB1_INT | IER_CLR); | 1270 | out_8(&via[IER], CB1_INT | IER_CLR); |
1288 | spin_unlock_irqrestore(&pmu_lock, flags); | 1271 | spin_unlock_irqrestore(&pmu_lock, flags); |
1289 | #endif /* SUSPEND_USES_PMU */ | ||
1290 | break; | 1272 | break; |
1291 | } | 1273 | } |
1292 | } while (1); | 1274 | } while (1); |
@@ -1307,18 +1289,11 @@ pmu_resume(void) | |||
1307 | return; | 1289 | return; |
1308 | } | 1290 | } |
1309 | adb_int_pending = 1; | 1291 | adb_int_pending = 1; |
1310 | #ifdef SUSPEND_USES_PMU | ||
1311 | pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); | ||
1312 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
1313 | while(!req.complete) | ||
1314 | pmu_poll(); | ||
1315 | #else /* SUSPEND_USES_PMU */ | ||
1316 | if (gpio_irq >= 0) | 1292 | if (gpio_irq >= 0) |
1317 | enable_irq(gpio_irq); | 1293 | enable_irq(gpio_irq); |
1318 | out_8(&via[IER], CB1_INT | IER_SET); | 1294 | out_8(&via[IER], CB1_INT | IER_SET); |
1319 | spin_unlock_irqrestore(&pmu_lock, flags); | 1295 | spin_unlock_irqrestore(&pmu_lock, flags); |
1320 | pmu_poll(); | 1296 | pmu_poll(); |
1321 | #endif /* SUSPEND_USES_PMU */ | ||
1322 | } | 1297 | } |
1323 | 1298 | ||
1324 | /* Interrupt data could be the result data from an ADB cmd */ | 1299 | /* Interrupt data could be the result data from an ADB cmd */ |
@@ -1738,228 +1713,7 @@ pmu_present(void) | |||
1738 | return via != 0; | 1713 | return via != 0; |
1739 | } | 1714 | } |
1740 | 1715 | ||
1741 | #ifdef CONFIG_PM_SLEEP | 1716 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) |
1742 | |||
1743 | static LIST_HEAD(sleep_notifiers); | ||
1744 | |||
1745 | int | ||
1746 | pmu_register_sleep_notifier(struct pmu_sleep_notifier *n) | ||
1747 | { | ||
1748 | struct list_head *list; | ||
1749 | struct pmu_sleep_notifier *notifier; | ||
1750 | |||
1751 | for (list = sleep_notifiers.next; list != &sleep_notifiers; | ||
1752 | list = list->next) { | ||
1753 | notifier = list_entry(list, struct pmu_sleep_notifier, list); | ||
1754 | if (n->priority > notifier->priority) | ||
1755 | break; | ||
1756 | } | ||
1757 | __list_add(&n->list, list->prev, list); | ||
1758 | return 0; | ||
1759 | } | ||
1760 | EXPORT_SYMBOL(pmu_register_sleep_notifier); | ||
1761 | |||
1762 | int | ||
1763 | pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n) | ||
1764 | { | ||
1765 | if (n->list.next == 0) | ||
1766 | return -ENOENT; | ||
1767 | list_del(&n->list); | ||
1768 | n->list.next = NULL; | ||
1769 | return 0; | ||
1770 | } | ||
1771 | EXPORT_SYMBOL(pmu_unregister_sleep_notifier); | ||
1772 | #endif /* CONFIG_PM_SLEEP */ | ||
1773 | |||
1774 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) | ||
1775 | |||
1776 | /* Sleep is broadcast last-to-first */ | ||
1777 | static void broadcast_sleep(int when) | ||
1778 | { | ||
1779 | struct list_head *list; | ||
1780 | struct pmu_sleep_notifier *notifier; | ||
1781 | |||
1782 | for (list = sleep_notifiers.prev; list != &sleep_notifiers; | ||
1783 | list = list->prev) { | ||
1784 | notifier = list_entry(list, struct pmu_sleep_notifier, list); | ||
1785 | notifier->notifier_call(notifier, when); | ||
1786 | } | ||
1787 | } | ||
1788 | |||
1789 | /* Wake is broadcast first-to-last */ | ||
1790 | static void broadcast_wake(void) | ||
1791 | { | ||
1792 | struct list_head *list; | ||
1793 | struct pmu_sleep_notifier *notifier; | ||
1794 | |||
1795 | for (list = sleep_notifiers.next; list != &sleep_notifiers; | ||
1796 | list = list->next) { | ||
1797 | notifier = list_entry(list, struct pmu_sleep_notifier, list); | ||
1798 | notifier->notifier_call(notifier, PBOOK_WAKE); | ||
1799 | } | ||
1800 | } | ||
1801 | |||
1802 | /* | ||
1803 | * This struct is used to store config register values for | ||
1804 | * PCI devices which may get powered off when we sleep. | ||
1805 | */ | ||
1806 | static struct pci_save { | ||
1807 | #ifndef HACKED_PCI_SAVE | ||
1808 | u16 command; | ||
1809 | u16 cache_lat; | ||
1810 | u16 intr; | ||
1811 | u32 rom_address; | ||
1812 | #else | ||
1813 | u32 config[16]; | ||
1814 | #endif | ||
1815 | } *pbook_pci_saves; | ||
1816 | static int pbook_npci_saves; | ||
1817 | |||
1818 | static void | ||
1819 | pbook_alloc_pci_save(void) | ||
1820 | { | ||
1821 | int npci; | ||
1822 | struct pci_dev *pd = NULL; | ||
1823 | |||
1824 | npci = 0; | ||
1825 | while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { | ||
1826 | ++npci; | ||
1827 | } | ||
1828 | if (npci == 0) | ||
1829 | return; | ||
1830 | pbook_pci_saves = (struct pci_save *) | ||
1831 | kmalloc(npci * sizeof(struct pci_save), GFP_KERNEL); | ||
1832 | pbook_npci_saves = npci; | ||
1833 | } | ||
1834 | |||
1835 | static void | ||
1836 | pbook_free_pci_save(void) | ||
1837 | { | ||
1838 | if (pbook_pci_saves == NULL) | ||
1839 | return; | ||
1840 | kfree(pbook_pci_saves); | ||
1841 | pbook_pci_saves = NULL; | ||
1842 | pbook_npci_saves = 0; | ||
1843 | } | ||
1844 | |||
1845 | static void | ||
1846 | pbook_pci_save(void) | ||
1847 | { | ||
1848 | struct pci_save *ps = pbook_pci_saves; | ||
1849 | struct pci_dev *pd = NULL; | ||
1850 | int npci = pbook_npci_saves; | ||
1851 | |||
1852 | if (ps == NULL) | ||
1853 | return; | ||
1854 | |||
1855 | while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { | ||
1856 | if (npci-- == 0) { | ||
1857 | pci_dev_put(pd); | ||
1858 | return; | ||
1859 | } | ||
1860 | #ifndef HACKED_PCI_SAVE | ||
1861 | pci_read_config_word(pd, PCI_COMMAND, &ps->command); | ||
1862 | pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat); | ||
1863 | pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr); | ||
1864 | pci_read_config_dword(pd, PCI_ROM_ADDRESS, &ps->rom_address); | ||
1865 | #else | ||
1866 | int i; | ||
1867 | for (i=1;i<16;i++) | ||
1868 | pci_read_config_dword(pd, i<<4, &ps->config[i]); | ||
1869 | #endif | ||
1870 | ++ps; | ||
1871 | } | ||
1872 | } | ||
1873 | |||
1874 | /* For this to work, we must take care of a few things: If gmac was enabled | ||
1875 | * during boot, it will be in the pci dev list. If it's disabled at this point | ||
1876 | * (and it will probably be), then you can't access it's config space. | ||
1877 | */ | ||
1878 | static void | ||
1879 | pbook_pci_restore(void) | ||
1880 | { | ||
1881 | u16 cmd; | ||
1882 | struct pci_save *ps = pbook_pci_saves - 1; | ||
1883 | struct pci_dev *pd = NULL; | ||
1884 | int npci = pbook_npci_saves; | ||
1885 | int j; | ||
1886 | |||
1887 | while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { | ||
1888 | #ifdef HACKED_PCI_SAVE | ||
1889 | int i; | ||
1890 | if (npci-- == 0) { | ||
1891 | pci_dev_put(pd); | ||
1892 | return; | ||
1893 | } | ||
1894 | ps++; | ||
1895 | for (i=2;i<16;i++) | ||
1896 | pci_write_config_dword(pd, i<<4, ps->config[i]); | ||
1897 | pci_write_config_dword(pd, 4, ps->config[1]); | ||
1898 | #else | ||
1899 | if (npci-- == 0) | ||
1900 | return; | ||
1901 | ps++; | ||
1902 | if (ps->command == 0) | ||
1903 | continue; | ||
1904 | pci_read_config_word(pd, PCI_COMMAND, &cmd); | ||
1905 | if ((ps->command & ~cmd) == 0) | ||
1906 | continue; | ||
1907 | switch (pd->hdr_type) { | ||
1908 | case PCI_HEADER_TYPE_NORMAL: | ||
1909 | for (j = 0; j < 6; ++j) | ||
1910 | pci_write_config_dword(pd, | ||
1911 | PCI_BASE_ADDRESS_0 + j*4, | ||
1912 | pd->resource[j].start); | ||
1913 | pci_write_config_dword(pd, PCI_ROM_ADDRESS, | ||
1914 | ps->rom_address); | ||
1915 | pci_write_config_word(pd, PCI_CACHE_LINE_SIZE, | ||
1916 | ps->cache_lat); | ||
1917 | pci_write_config_word(pd, PCI_INTERRUPT_LINE, | ||
1918 | ps->intr); | ||
1919 | pci_write_config_word(pd, PCI_COMMAND, ps->command); | ||
1920 | break; | ||
1921 | } | ||
1922 | #endif | ||
1923 | } | ||
1924 | } | ||
1925 | |||
1926 | #ifdef DEBUG_SLEEP | ||
1927 | /* N.B. This doesn't work on the 3400 */ | ||
1928 | void | ||
1929 | pmu_blink(int n) | ||
1930 | { | ||
1931 | struct adb_request req; | ||
1932 | |||
1933 | memset(&req, 0, sizeof(req)); | ||
1934 | |||
1935 | for (; n > 0; --n) { | ||
1936 | req.nbytes = 4; | ||
1937 | req.done = NULL; | ||
1938 | req.data[0] = 0xee; | ||
1939 | req.data[1] = 4; | ||
1940 | req.data[2] = 0; | ||
1941 | req.data[3] = 1; | ||
1942 | req.reply[0] = ADB_RET_OK; | ||
1943 | req.reply_len = 1; | ||
1944 | req.reply_expected = 0; | ||
1945 | pmu_polled_request(&req); | ||
1946 | mdelay(50); | ||
1947 | req.nbytes = 4; | ||
1948 | req.done = NULL; | ||
1949 | req.data[0] = 0xee; | ||
1950 | req.data[1] = 4; | ||
1951 | req.data[2] = 0; | ||
1952 | req.data[3] = 0; | ||
1953 | req.reply[0] = ADB_RET_OK; | ||
1954 | req.reply_len = 1; | ||
1955 | req.reply_expected = 0; | ||
1956 | pmu_polled_request(&req); | ||
1957 | mdelay(50); | ||
1958 | } | ||
1959 | mdelay(50); | ||
1960 | } | ||
1961 | #endif | ||
1962 | |||
1963 | /* | 1717 | /* |
1964 | * Put the powerbook to sleep. | 1718 | * Put the powerbook to sleep. |
1965 | */ | 1719 | */ |
@@ -1994,134 +1748,6 @@ restore_via_state(void) | |||
1994 | out_8(&via[IER], IER_SET | SR_INT | CB1_INT); | 1748 | out_8(&via[IER], IER_SET | SR_INT | CB1_INT); |
1995 | } | 1749 | } |
1996 | 1750 | ||
1997 | extern void pmu_backlight_set_sleep(int sleep); | ||
1998 | |||
1999 | static int | ||
2000 | pmac_suspend_devices(void) | ||
2001 | { | ||
2002 | int ret; | ||
2003 | |||
2004 | pm_prepare_console(); | ||
2005 | |||
2006 | /* Notify old-style device drivers */ | ||
2007 | broadcast_sleep(PBOOK_SLEEP_REQUEST); | ||
2008 | |||
2009 | /* Sync the disks. */ | ||
2010 | /* XXX It would be nice to have some way to ensure that | ||
2011 | * nobody is dirtying any new buffers while we wait. That | ||
2012 | * could be achieved using the refrigerator for processes | ||
2013 | * that swsusp uses | ||
2014 | */ | ||
2015 | sys_sync(); | ||
2016 | |||
2017 | broadcast_sleep(PBOOK_SLEEP_NOW); | ||
2018 | |||
2019 | /* Send suspend call to devices, hold the device core's dpm_sem */ | ||
2020 | ret = device_suspend(PMSG_SUSPEND); | ||
2021 | if (ret) { | ||
2022 | broadcast_wake(); | ||
2023 | printk(KERN_ERR "Driver sleep failed\n"); | ||
2024 | return -EBUSY; | ||
2025 | } | ||
2026 | |||
2027 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
2028 | /* Tell backlight code not to muck around with the chip anymore */ | ||
2029 | pmu_backlight_set_sleep(1); | ||
2030 | #endif | ||
2031 | |||
2032 | /* Call platform functions marked "on sleep" */ | ||
2033 | pmac_pfunc_i2c_suspend(); | ||
2034 | pmac_pfunc_base_suspend(); | ||
2035 | |||
2036 | /* Stop preemption */ | ||
2037 | preempt_disable(); | ||
2038 | |||
2039 | /* Make sure the decrementer won't interrupt us */ | ||
2040 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); | ||
2041 | /* Make sure any pending DEC interrupt occurring while we did | ||
2042 | * the above didn't re-enable the DEC */ | ||
2043 | mb(); | ||
2044 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); | ||
2045 | |||
2046 | /* We can now disable MSR_EE. This code of course works properly only | ||
2047 | * on UP machines... For SMP, if we ever implement sleep, we'll have to | ||
2048 | * stop the "other" CPUs way before we do all that stuff. | ||
2049 | */ | ||
2050 | local_irq_disable(); | ||
2051 | |||
2052 | /* Broadcast power down irq | ||
2053 | * This isn't that useful in most cases (only directly wired devices can | ||
2054 | * use this but still... This will take care of sysdev's as well, so | ||
2055 | * we exit from here with local irqs disabled and PIC off. | ||
2056 | */ | ||
2057 | ret = device_power_down(PMSG_SUSPEND); | ||
2058 | if (ret) { | ||
2059 | wakeup_decrementer(); | ||
2060 | local_irq_enable(); | ||
2061 | preempt_enable(); | ||
2062 | device_resume(); | ||
2063 | broadcast_wake(); | ||
2064 | printk(KERN_ERR "Driver powerdown failed\n"); | ||
2065 | return -EBUSY; | ||
2066 | } | ||
2067 | |||
2068 | /* Wait for completion of async requests */ | ||
2069 | while (!batt_req.complete) | ||
2070 | pmu_poll(); | ||
2071 | |||
2072 | /* Giveup the lazy FPU & vec so we don't have to back them | ||
2073 | * up from the low level code | ||
2074 | */ | ||
2075 | enable_kernel_fp(); | ||
2076 | |||
2077 | #ifdef CONFIG_ALTIVEC | ||
2078 | if (cpu_has_feature(CPU_FTR_ALTIVEC)) | ||
2079 | enable_kernel_altivec(); | ||
2080 | #endif /* CONFIG_ALTIVEC */ | ||
2081 | |||
2082 | return 0; | ||
2083 | } | ||
2084 | |||
2085 | static int | ||
2086 | pmac_wakeup_devices(void) | ||
2087 | { | ||
2088 | mdelay(100); | ||
2089 | |||
2090 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
2091 | /* Tell backlight code it can use the chip again */ | ||
2092 | pmu_backlight_set_sleep(0); | ||
2093 | #endif | ||
2094 | |||
2095 | /* Power back up system devices (including the PIC) */ | ||
2096 | device_power_up(); | ||
2097 | |||
2098 | /* Force a poll of ADB interrupts */ | ||
2099 | adb_int_pending = 1; | ||
2100 | via_pmu_interrupt(0, NULL); | ||
2101 | |||
2102 | /* Restart jiffies & scheduling */ | ||
2103 | wakeup_decrementer(); | ||
2104 | |||
2105 | /* Re-enable local CPU interrupts */ | ||
2106 | local_irq_enable(); | ||
2107 | mdelay(10); | ||
2108 | preempt_enable(); | ||
2109 | |||
2110 | /* Call platform functions marked "on wake" */ | ||
2111 | pmac_pfunc_base_resume(); | ||
2112 | pmac_pfunc_i2c_resume(); | ||
2113 | |||
2114 | /* Resume devices */ | ||
2115 | device_resume(); | ||
2116 | |||
2117 | /* Notify old style drivers */ | ||
2118 | broadcast_wake(); | ||
2119 | |||
2120 | pm_restore_console(); | ||
2121 | |||
2122 | return 0; | ||
2123 | } | ||
2124 | |||
2125 | #define GRACKLE_PM (1<<7) | 1751 | #define GRACKLE_PM (1<<7) |
2126 | #define GRACKLE_DOZE (1<<5) | 1752 | #define GRACKLE_DOZE (1<<5) |
2127 | #define GRACKLE_NAP (1<<4) | 1753 | #define GRACKLE_NAP (1<<4) |
@@ -2132,19 +1758,12 @@ static int powerbook_sleep_grackle(void) | |||
2132 | unsigned long save_l2cr; | 1758 | unsigned long save_l2cr; |
2133 | unsigned short pmcr1; | 1759 | unsigned short pmcr1; |
2134 | struct adb_request req; | 1760 | struct adb_request req; |
2135 | int ret; | ||
2136 | struct pci_dev *grackle; | 1761 | struct pci_dev *grackle; |
2137 | 1762 | ||
2138 | grackle = pci_get_bus_and_slot(0, 0); | 1763 | grackle = pci_get_bus_and_slot(0, 0); |
2139 | if (!grackle) | 1764 | if (!grackle) |
2140 | return -ENODEV; | 1765 | return -ENODEV; |
2141 | 1766 | ||
2142 | ret = pmac_suspend_devices(); | ||
2143 | if (ret) { | ||
2144 | printk(KERN_ERR "Sleep rejected by devices\n"); | ||
2145 | return ret; | ||
2146 | } | ||
2147 | |||
2148 | /* Turn off various things. Darwin does some retry tests here... */ | 1767 | /* Turn off various things. Darwin does some retry tests here... */ |
2149 | pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE); | 1768 | pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE); |
2150 | pmu_wait_complete(&req); | 1769 | pmu_wait_complete(&req); |
@@ -2207,8 +1826,6 @@ static int powerbook_sleep_grackle(void) | |||
2207 | PMU_POW_ON|PMU_POW_BACKLIGHT|PMU_POW_CHARGER|PMU_POW_IRLED|PMU_POW_MEDIABAY); | 1826 | PMU_POW_ON|PMU_POW_BACKLIGHT|PMU_POW_CHARGER|PMU_POW_IRLED|PMU_POW_MEDIABAY); |
2208 | pmu_wait_complete(&req); | 1827 | pmu_wait_complete(&req); |
2209 | 1828 | ||
2210 | pmac_wakeup_devices(); | ||
2211 | |||
2212 | return 0; | 1829 | return 0; |
2213 | } | 1830 | } |
2214 | 1831 | ||
@@ -2218,7 +1835,6 @@ powerbook_sleep_Core99(void) | |||
2218 | unsigned long save_l2cr; | 1835 | unsigned long save_l2cr; |
2219 | unsigned long save_l3cr; | 1836 | unsigned long save_l3cr; |
2220 | struct adb_request req; | 1837 | struct adb_request req; |
2221 | int ret; | ||
2222 | 1838 | ||
2223 | if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) { | 1839 | if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) { |
2224 | printk(KERN_ERR "Sleep mode not supported on this machine\n"); | 1840 | printk(KERN_ERR "Sleep mode not supported on this machine\n"); |
@@ -2228,12 +1844,6 @@ powerbook_sleep_Core99(void) | |||
2228 | if (num_online_cpus() > 1 || cpu_is_offline(0)) | 1844 | if (num_online_cpus() > 1 || cpu_is_offline(0)) |
2229 | return -EAGAIN; | 1845 | return -EAGAIN; |
2230 | 1846 | ||
2231 | ret = pmac_suspend_devices(); | ||
2232 | if (ret) { | ||
2233 | printk(KERN_ERR "Sleep rejected by devices\n"); | ||
2234 | return ret; | ||
2235 | } | ||
2236 | |||
2237 | /* Stop environment and ADB interrupts */ | 1847 | /* Stop environment and ADB interrupts */ |
2238 | pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0); | 1848 | pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0); |
2239 | pmu_wait_complete(&req); | 1849 | pmu_wait_complete(&req); |
@@ -2304,45 +1914,33 @@ powerbook_sleep_Core99(void) | |||
2304 | /* Restore LPJ, cpufreq will adjust the cpu frequency */ | 1914 | /* Restore LPJ, cpufreq will adjust the cpu frequency */ |
2305 | loops_per_jiffy /= 2; | 1915 | loops_per_jiffy /= 2; |
2306 | 1916 | ||
2307 | pmac_wakeup_devices(); | ||
2308 | |||
2309 | return 0; | 1917 | return 0; |
2310 | } | 1918 | } |
2311 | 1919 | ||
2312 | #define PB3400_MEM_CTRL 0xf8000000 | 1920 | #define PB3400_MEM_CTRL 0xf8000000 |
2313 | #define PB3400_MEM_CTRL_SLEEP 0x70 | 1921 | #define PB3400_MEM_CTRL_SLEEP 0x70 |
2314 | 1922 | ||
2315 | static int | 1923 | static void __iomem *pb3400_mem_ctrl; |
2316 | powerbook_sleep_3400(void) | 1924 | |
1925 | static void powerbook_sleep_init_3400(void) | ||
1926 | { | ||
1927 | /* map in the memory controller registers */ | ||
1928 | pb3400_mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100); | ||
1929 | if (pb3400_mem_ctrl == NULL) | ||
1930 | printk(KERN_WARNING "ioremap failed: sleep won't be possible"); | ||
1931 | } | ||
1932 | |||
1933 | static int powerbook_sleep_3400(void) | ||
2317 | { | 1934 | { |
2318 | int ret, i, x; | 1935 | int i, x; |
2319 | unsigned int hid0; | 1936 | unsigned int hid0; |
2320 | unsigned long p; | 1937 | unsigned long msr; |
2321 | struct adb_request sleep_req; | 1938 | struct adb_request sleep_req; |
2322 | void __iomem *mem_ctrl; | ||
2323 | unsigned int __iomem *mem_ctrl_sleep; | 1939 | unsigned int __iomem *mem_ctrl_sleep; |
2324 | 1940 | ||
2325 | /* first map in the memory controller registers */ | 1941 | if (pb3400_mem_ctrl == NULL) |
2326 | mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100); | ||
2327 | if (mem_ctrl == NULL) { | ||
2328 | printk("powerbook_sleep_3400: ioremap failed\n"); | ||
2329 | return -ENOMEM; | 1942 | return -ENOMEM; |
2330 | } | 1943 | mem_ctrl_sleep = pb3400_mem_ctrl + PB3400_MEM_CTRL_SLEEP; |
2331 | mem_ctrl_sleep = mem_ctrl + PB3400_MEM_CTRL_SLEEP; | ||
2332 | |||
2333 | /* Allocate room for PCI save */ | ||
2334 | pbook_alloc_pci_save(); | ||
2335 | |||
2336 | ret = pmac_suspend_devices(); | ||
2337 | if (ret) { | ||
2338 | pbook_free_pci_save(); | ||
2339 | iounmap(mem_ctrl); | ||
2340 | printk(KERN_ERR "Sleep rejected by devices\n"); | ||
2341 | return ret; | ||
2342 | } | ||
2343 | |||
2344 | /* Save the state of PCI config space for some slots */ | ||
2345 | pbook_pci_save(); | ||
2346 | 1944 | ||
2347 | /* Set the memory controller to keep the memory refreshed | 1945 | /* Set the memory controller to keep the memory refreshed |
2348 | while we're asleep */ | 1946 | while we're asleep */ |
@@ -2357,41 +1955,34 @@ powerbook_sleep_3400(void) | |||
2357 | 1955 | ||
2358 | /* Ask the PMU to put us to sleep */ | 1956 | /* Ask the PMU to put us to sleep */ |
2359 | pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); | 1957 | pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); |
2360 | while (!sleep_req.complete) | 1958 | pmu_wait_complete(&sleep_req); |
2361 | mb(); | 1959 | pmu_unlock(); |
2362 | 1960 | ||
2363 | pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,1); | 1961 | pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, 1); |
2364 | 1962 | ||
2365 | /* displacement-flush the L2 cache - necessary? */ | ||
2366 | for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000) | ||
2367 | i = *(volatile int *)p; | ||
2368 | asleep = 1; | 1963 | asleep = 1; |
2369 | 1964 | ||
2370 | /* Put the CPU into sleep mode */ | 1965 | /* Put the CPU into sleep mode */ |
2371 | hid0 = mfspr(SPRN_HID0); | 1966 | hid0 = mfspr(SPRN_HID0); |
2372 | hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP; | 1967 | hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP; |
2373 | mtspr(SPRN_HID0, hid0); | 1968 | mtspr(SPRN_HID0, hid0); |
2374 | mtmsr(mfmsr() | MSR_POW | MSR_EE); | 1969 | local_irq_enable(); |
2375 | udelay(10); | 1970 | msr = mfmsr() | MSR_POW; |
1971 | while (asleep) { | ||
1972 | mb(); | ||
1973 | mtmsr(msr); | ||
1974 | isync(); | ||
1975 | } | ||
1976 | local_irq_disable(); | ||
2376 | 1977 | ||
2377 | /* OK, we're awake again, start restoring things */ | 1978 | /* OK, we're awake again, start restoring things */ |
2378 | out_be32(mem_ctrl_sleep, 0x3f); | 1979 | out_be32(mem_ctrl_sleep, 0x3f); |
2379 | pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,0); | 1980 | pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, 0); |
2380 | pbook_pci_restore(); | ||
2381 | pmu_unlock(); | ||
2382 | |||
2383 | /* wait for the PMU interrupt sequence to complete */ | ||
2384 | while (asleep) | ||
2385 | mb(); | ||
2386 | |||
2387 | pmac_wakeup_devices(); | ||
2388 | pbook_free_pci_save(); | ||
2389 | iounmap(mem_ctrl); | ||
2390 | 1981 | ||
2391 | return 0; | 1982 | return 0; |
2392 | } | 1983 | } |
2393 | 1984 | ||
2394 | #endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ | 1985 | #endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ |
2395 | 1986 | ||
2396 | /* | 1987 | /* |
2397 | * Support for /dev/pmu device | 1988 | * Support for /dev/pmu device |
@@ -2548,7 +2139,6 @@ pmu_release(struct inode *inode, struct file *file) | |||
2548 | struct pmu_private *pp = file->private_data; | 2139 | struct pmu_private *pp = file->private_data; |
2549 | unsigned long flags; | 2140 | unsigned long flags; |
2550 | 2141 | ||
2551 | lock_kernel(); | ||
2552 | if (pp != 0) { | 2142 | if (pp != 0) { |
2553 | file->private_data = NULL; | 2143 | file->private_data = NULL; |
2554 | spin_lock_irqsave(&all_pvt_lock, flags); | 2144 | spin_lock_irqsave(&all_pvt_lock, flags); |
@@ -2562,10 +2152,96 @@ pmu_release(struct inode *inode, struct file *file) | |||
2562 | 2152 | ||
2563 | kfree(pp); | 2153 | kfree(pp); |
2564 | } | 2154 | } |
2565 | unlock_kernel(); | ||
2566 | return 0; | 2155 | return 0; |
2567 | } | 2156 | } |
2568 | 2157 | ||
2158 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) | ||
2159 | static void pmac_suspend_disable_irqs(void) | ||
2160 | { | ||
2161 | /* Call platform functions marked "on sleep" */ | ||
2162 | pmac_pfunc_i2c_suspend(); | ||
2163 | pmac_pfunc_base_suspend(); | ||
2164 | } | ||
2165 | |||
2166 | static int powerbook_sleep(suspend_state_t state) | ||
2167 | { | ||
2168 | int error = 0; | ||
2169 | |||
2170 | /* Wait for completion of async requests */ | ||
2171 | while (!batt_req.complete) | ||
2172 | pmu_poll(); | ||
2173 | |||
2174 | /* Giveup the lazy FPU & vec so we don't have to back them | ||
2175 | * up from the low level code | ||
2176 | */ | ||
2177 | enable_kernel_fp(); | ||
2178 | |||
2179 | #ifdef CONFIG_ALTIVEC | ||
2180 | if (cpu_has_feature(CPU_FTR_ALTIVEC)) | ||
2181 | enable_kernel_altivec(); | ||
2182 | #endif /* CONFIG_ALTIVEC */ | ||
2183 | |||
2184 | switch (pmu_kind) { | ||
2185 | case PMU_OHARE_BASED: | ||
2186 | error = powerbook_sleep_3400(); | ||
2187 | break; | ||
2188 | case PMU_HEATHROW_BASED: | ||
2189 | case PMU_PADDINGTON_BASED: | ||
2190 | error = powerbook_sleep_grackle(); | ||
2191 | break; | ||
2192 | case PMU_KEYLARGO_BASED: | ||
2193 | error = powerbook_sleep_Core99(); | ||
2194 | break; | ||
2195 | default: | ||
2196 | return -ENOSYS; | ||
2197 | } | ||
2198 | |||
2199 | if (error) | ||
2200 | return error; | ||
2201 | |||
2202 | mdelay(100); | ||
2203 | |||
2204 | return 0; | ||
2205 | } | ||
2206 | |||
2207 | static void pmac_suspend_enable_irqs(void) | ||
2208 | { | ||
2209 | /* Force a poll of ADB interrupts */ | ||
2210 | adb_int_pending = 1; | ||
2211 | via_pmu_interrupt(0, NULL); | ||
2212 | |||
2213 | mdelay(10); | ||
2214 | |||
2215 | /* Call platform functions marked "on wake" */ | ||
2216 | pmac_pfunc_base_resume(); | ||
2217 | pmac_pfunc_i2c_resume(); | ||
2218 | } | ||
2219 | |||
2220 | static int pmu_sleep_valid(suspend_state_t state) | ||
2221 | { | ||
2222 | return state == PM_SUSPEND_MEM | ||
2223 | && (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0); | ||
2224 | } | ||
2225 | |||
2226 | static struct platform_suspend_ops pmu_pm_ops = { | ||
2227 | .enter = powerbook_sleep, | ||
2228 | .valid = pmu_sleep_valid, | ||
2229 | }; | ||
2230 | |||
2231 | static int register_pmu_pm_ops(void) | ||
2232 | { | ||
2233 | if (pmu_kind == PMU_OHARE_BASED) | ||
2234 | powerbook_sleep_init_3400(); | ||
2235 | ppc_md.suspend_disable_irqs = pmac_suspend_disable_irqs; | ||
2236 | ppc_md.suspend_enable_irqs = pmac_suspend_enable_irqs; | ||
2237 | suspend_set_ops(&pmu_pm_ops); | ||
2238 | |||
2239 | return 0; | ||
2240 | } | ||
2241 | |||
2242 | device_initcall(register_pmu_pm_ops); | ||
2243 | #endif | ||
2244 | |||
2569 | static int | 2245 | static int |
2570 | pmu_ioctl(struct inode * inode, struct file *filp, | 2246 | pmu_ioctl(struct inode * inode, struct file *filp, |
2571 | u_int cmd, u_long arg) | 2247 | u_int cmd, u_long arg) |
@@ -2574,35 +2250,15 @@ pmu_ioctl(struct inode * inode, struct file *filp, | |||
2574 | int error = -EINVAL; | 2250 | int error = -EINVAL; |
2575 | 2251 | ||
2576 | switch (cmd) { | 2252 | switch (cmd) { |
2577 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) | ||
2578 | case PMU_IOC_SLEEP: | 2253 | case PMU_IOC_SLEEP: |
2579 | if (!capable(CAP_SYS_ADMIN)) | 2254 | if (!capable(CAP_SYS_ADMIN)) |
2580 | return -EACCES; | 2255 | return -EACCES; |
2581 | if (sleep_in_progress) | 2256 | return pm_suspend(PM_SUSPEND_MEM); |
2582 | return -EBUSY; | ||
2583 | sleep_in_progress = 1; | ||
2584 | switch (pmu_kind) { | ||
2585 | case PMU_OHARE_BASED: | ||
2586 | error = powerbook_sleep_3400(); | ||
2587 | break; | ||
2588 | case PMU_HEATHROW_BASED: | ||
2589 | case PMU_PADDINGTON_BASED: | ||
2590 | error = powerbook_sleep_grackle(); | ||
2591 | break; | ||
2592 | case PMU_KEYLARGO_BASED: | ||
2593 | error = powerbook_sleep_Core99(); | ||
2594 | break; | ||
2595 | default: | ||
2596 | error = -ENOSYS; | ||
2597 | } | ||
2598 | sleep_in_progress = 0; | ||
2599 | break; | ||
2600 | case PMU_IOC_CAN_SLEEP: | 2257 | case PMU_IOC_CAN_SLEEP: |
2601 | if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) | 2258 | if (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) < 0) |
2602 | return put_user(0, argp); | 2259 | return put_user(0, argp); |
2603 | else | 2260 | else |
2604 | return put_user(1, argp); | 2261 | return put_user(1, argp); |
2605 | #endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ | ||
2606 | 2262 | ||
2607 | #ifdef CONFIG_PMAC_BACKLIGHT_LEGACY | 2263 | #ifdef CONFIG_PMAC_BACKLIGHT_LEGACY |
2608 | /* Compatibility ioctl's for backlight */ | 2264 | /* Compatibility ioctl's for backlight */ |
@@ -2610,9 +2266,6 @@ pmu_ioctl(struct inode * inode, struct file *filp, | |||
2610 | { | 2266 | { |
2611 | int brightness; | 2267 | int brightness; |
2612 | 2268 | ||
2613 | if (sleep_in_progress) | ||
2614 | return -EBUSY; | ||
2615 | |||
2616 | brightness = pmac_backlight_get_legacy_brightness(); | 2269 | brightness = pmac_backlight_get_legacy_brightness(); |
2617 | if (brightness < 0) | 2270 | if (brightness < 0) |
2618 | return brightness; | 2271 | return brightness; |
@@ -2624,9 +2277,6 @@ pmu_ioctl(struct inode * inode, struct file *filp, | |||
2624 | { | 2277 | { |
2625 | int brightness; | 2278 | int brightness; |
2626 | 2279 | ||
2627 | if (sleep_in_progress) | ||
2628 | return -EBUSY; | ||
2629 | |||
2630 | error = get_user(brightness, argp); | 2280 | error = get_user(brightness, argp); |
2631 | if (error) | 2281 | if (error) |
2632 | return error; | 2282 | return error; |
@@ -2751,15 +2401,43 @@ pmu_polled_request(struct adb_request *req) | |||
2751 | local_irq_restore(flags); | 2401 | local_irq_restore(flags); |
2752 | return 0; | 2402 | return 0; |
2753 | } | 2403 | } |
2754 | #endif /* DEBUG_SLEEP */ | ||
2755 | 2404 | ||
2405 | /* N.B. This doesn't work on the 3400 */ | ||
2406 | void pmu_blink(int n) | ||
2407 | { | ||
2408 | struct adb_request req; | ||
2756 | 2409 | ||
2757 | /* FIXME: This is a temporary set of callbacks to enable us | 2410 | memset(&req, 0, sizeof(req)); |
2758 | * to do suspend-to-disk. | ||
2759 | */ | ||
2760 | 2411 | ||
2761 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) | 2412 | for (; n > 0; --n) { |
2413 | req.nbytes = 4; | ||
2414 | req.done = NULL; | ||
2415 | req.data[0] = 0xee; | ||
2416 | req.data[1] = 4; | ||
2417 | req.data[2] = 0; | ||
2418 | req.data[3] = 1; | ||
2419 | req.reply[0] = ADB_RET_OK; | ||
2420 | req.reply_len = 1; | ||
2421 | req.reply_expected = 0; | ||
2422 | pmu_polled_request(&req); | ||
2423 | mdelay(50); | ||
2424 | req.nbytes = 4; | ||
2425 | req.done = NULL; | ||
2426 | req.data[0] = 0xee; | ||
2427 | req.data[1] = 4; | ||
2428 | req.data[2] = 0; | ||
2429 | req.data[3] = 0; | ||
2430 | req.reply[0] = ADB_RET_OK; | ||
2431 | req.reply_len = 1; | ||
2432 | req.reply_expected = 0; | ||
2433 | pmu_polled_request(&req); | ||
2434 | mdelay(50); | ||
2435 | } | ||
2436 | mdelay(50); | ||
2437 | } | ||
2438 | #endif /* DEBUG_SLEEP */ | ||
2762 | 2439 | ||
2440 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) | ||
2763 | int pmu_sys_suspended; | 2441 | int pmu_sys_suspended; |
2764 | 2442 | ||
2765 | static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state) | 2443 | static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state) |
@@ -2767,10 +2445,15 @@ static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state) | |||
2767 | if (state.event != PM_EVENT_SUSPEND || pmu_sys_suspended) | 2445 | if (state.event != PM_EVENT_SUSPEND || pmu_sys_suspended) |
2768 | return 0; | 2446 | return 0; |
2769 | 2447 | ||
2770 | /* Suspend PMU event interrupts */ | 2448 | /* Suspend PMU event interrupts */\ |
2771 | pmu_suspend(); | 2449 | pmu_suspend(); |
2772 | |||
2773 | pmu_sys_suspended = 1; | 2450 | pmu_sys_suspended = 1; |
2451 | |||
2452 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
2453 | /* Tell backlight code not to muck around with the chip anymore */ | ||
2454 | pmu_backlight_set_sleep(1); | ||
2455 | #endif | ||
2456 | |||
2774 | return 0; | 2457 | return 0; |
2775 | } | 2458 | } |
2776 | 2459 | ||
@@ -2785,15 +2468,18 @@ static int pmu_sys_resume(struct sys_device *sysdev) | |||
2785 | pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2); | 2468 | pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2); |
2786 | pmu_wait_complete(&req); | 2469 | pmu_wait_complete(&req); |
2787 | 2470 | ||
2471 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
2472 | /* Tell backlight code it can use the chip again */ | ||
2473 | pmu_backlight_set_sleep(0); | ||
2474 | #endif | ||
2788 | /* Resume PMU event interrupts */ | 2475 | /* Resume PMU event interrupts */ |
2789 | pmu_resume(); | 2476 | pmu_resume(); |
2790 | |||
2791 | pmu_sys_suspended = 0; | 2477 | pmu_sys_suspended = 0; |
2792 | 2478 | ||
2793 | return 0; | 2479 | return 0; |
2794 | } | 2480 | } |
2795 | 2481 | ||
2796 | #endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ | 2482 | #endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ |
2797 | 2483 | ||
2798 | static struct sysdev_class pmu_sysclass = { | 2484 | static struct sysdev_class pmu_sysclass = { |
2799 | .name = "pmu", | 2485 | .name = "pmu", |
@@ -2804,10 +2490,10 @@ static struct sys_device device_pmu = { | |||
2804 | }; | 2490 | }; |
2805 | 2491 | ||
2806 | static struct sysdev_driver driver_pmu = { | 2492 | static struct sysdev_driver driver_pmu = { |
2807 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) | 2493 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) |
2808 | .suspend = &pmu_sys_suspend, | 2494 | .suspend = &pmu_sys_suspend, |
2809 | .resume = &pmu_sys_resume, | 2495 | .resume = &pmu_sys_resume, |
2810 | #endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ | 2496 | #endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ |
2811 | }; | 2497 | }; |
2812 | 2498 | ||
2813 | static int __init init_pmu_sysfs(void) | 2499 | static int __init init_pmu_sysfs(void) |
@@ -2842,10 +2528,10 @@ EXPORT_SYMBOL(pmu_wait_complete); | |||
2842 | EXPORT_SYMBOL(pmu_suspend); | 2528 | EXPORT_SYMBOL(pmu_suspend); |
2843 | EXPORT_SYMBOL(pmu_resume); | 2529 | EXPORT_SYMBOL(pmu_resume); |
2844 | EXPORT_SYMBOL(pmu_unlock); | 2530 | EXPORT_SYMBOL(pmu_unlock); |
2845 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) | 2531 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) |
2846 | EXPORT_SYMBOL(pmu_enable_irled); | 2532 | EXPORT_SYMBOL(pmu_enable_irled); |
2847 | EXPORT_SYMBOL(pmu_battery_count); | 2533 | EXPORT_SYMBOL(pmu_battery_count); |
2848 | EXPORT_SYMBOL(pmu_batteries); | 2534 | EXPORT_SYMBOL(pmu_batteries); |
2849 | EXPORT_SYMBOL(pmu_power_flags); | 2535 | EXPORT_SYMBOL(pmu_power_flags); |
2850 | #endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ | 2536 | #endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ |
2851 | 2537 | ||
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6c575403bd39..389980f0e59e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -2356,7 +2356,7 @@ config GELIC_NET | |||
2356 | 2356 | ||
2357 | config GIANFAR | 2357 | config GIANFAR |
2358 | tristate "Gianfar Ethernet" | 2358 | tristate "Gianfar Ethernet" |
2359 | depends on 85xx || 83xx || PPC_86xx | 2359 | depends on FSL_SOC |
2360 | select PHYLIB | 2360 | select PHYLIB |
2361 | select CRC32 | 2361 | select CRC32 |
2362 | help | 2362 | help |
diff --git a/drivers/net/fec_8xx/fec_8xx-netta.c b/drivers/net/fec_8xx/fec_8xx-netta.c index e492eb84f948..79deee222e28 100644 --- a/drivers/net/fec_8xx/fec_8xx-netta.c +++ b/drivers/net/fec_8xx/fec_8xx-netta.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <asm/mpc8xx.h> | 26 | #include <asm/mpc8xx.h> |
27 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/commproc.h> | 29 | #include <asm/cpm1.h> |
30 | 30 | ||
31 | #include "fec_8xx.h" | 31 | #include "fec_8xx.h" |
32 | 32 | ||
diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c index ab9637ab3a8d..ca8d2e83ab03 100644 --- a/drivers/net/fec_8xx/fec_main.c +++ b/drivers/net/fec_8xx/fec_main.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <asm/mpc8xx.h> | 35 | #include <asm/mpc8xx.h> |
36 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | #include <asm/commproc.h> | 38 | #include <asm/cpm1.h> |
39 | 39 | ||
40 | #include "fec_8xx.h" | 40 | #include "fec_8xx.h" |
41 | 41 | ||
diff --git a/drivers/net/fec_8xx/fec_mii.c b/drivers/net/fec_8xx/fec_mii.c index e8e10a02d202..3b6ca29d31f2 100644 --- a/drivers/net/fec_8xx/fec_mii.c +++ b/drivers/net/fec_8xx/fec_mii.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <asm/mpc8xx.h> | 34 | #include <asm/mpc8xx.h> |
35 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
37 | #include <asm/commproc.h> | 37 | #include <asm/cpm1.h> |
38 | 38 | ||
39 | /*************************************************/ | 39 | /*************************************************/ |
40 | 40 | ||
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index f91ee700e605..58b71e60204e 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c | |||
@@ -1057,10 +1057,8 @@ static int mpc52xx_fec_of_resume(struct of_device *op) | |||
1057 | #endif | 1057 | #endif |
1058 | 1058 | ||
1059 | static struct of_device_id mpc52xx_fec_match[] = { | 1059 | static struct of_device_id mpc52xx_fec_match[] = { |
1060 | { | 1060 | { .type = "network", .compatible = "fsl,mpc5200-fec", }, |
1061 | .type = "network", | 1061 | { .type = "network", .compatible = "mpc5200-fec", }, |
1062 | .compatible = "mpc5200-fec", | ||
1063 | }, | ||
1064 | { } | 1062 | { } |
1065 | }; | 1063 | }; |
1066 | 1064 | ||
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index ba6e8b218e0a..1837584c4504 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c | |||
@@ -177,11 +177,9 @@ static int mpc52xx_fec_mdio_remove(struct of_device *of) | |||
177 | 177 | ||
178 | 178 | ||
179 | static struct of_device_id mpc52xx_fec_mdio_match[] = { | 179 | static struct of_device_id mpc52xx_fec_mdio_match[] = { |
180 | { | 180 | { .compatible = "fsl,mpc5200b-mdio", }, |
181 | .type = "mdio", | 181 | { .compatible = "mpc5200b-fec-phy", }, |
182 | .compatible = "mpc5200b-fec-phy", | 182 | {} |
183 | }, | ||
184 | {}, | ||
185 | }; | 183 | }; |
186 | 184 | ||
187 | struct of_platform_driver mpc52xx_fec_mdio_driver = { | 185 | struct of_platform_driver mpc52xx_fec_mdio_driver = { |
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index c83bd6560088..42d94edeee26 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
@@ -1178,8 +1178,15 @@ static int __devinit find_phy(struct device_node *np, | |||
1178 | struct device_node *phynode, *mdionode; | 1178 | struct device_node *phynode, *mdionode; |
1179 | struct resource res; | 1179 | struct resource res; |
1180 | int ret = 0, len; | 1180 | int ret = 0, len; |
1181 | const u32 *data; | ||
1182 | |||
1183 | data = of_get_property(np, "fixed-link", NULL); | ||
1184 | if (data) { | ||
1185 | snprintf(fpi->bus_id, 16, PHY_ID_FMT, 0, *data); | ||
1186 | return 0; | ||
1187 | } | ||
1181 | 1188 | ||
1182 | const u32 *data = of_get_property(np, "phy-handle", &len); | 1189 | data = of_get_property(np, "phy-handle", &len); |
1183 | if (!data || len != 4) | 1190 | if (!data || len != 4) |
1184 | return -EINVAL; | 1191 | return -EINVAL; |
1185 | 1192 | ||
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h index c675e29aadcc..e05389c49bbb 100644 --- a/drivers/net/fs_enet/fs_enet.h +++ b/drivers/net/fs_enet/fs_enet.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <asm/fs_pd.h> | 12 | #include <asm/fs_pd.h> |
13 | 13 | ||
14 | #ifdef CONFIG_CPM1 | 14 | #ifdef CONFIG_CPM1 |
15 | #include <asm/commproc.h> | 15 | #include <asm/cpm1.h> |
16 | 16 | ||
17 | struct fec_info { | 17 | struct fec_info { |
18 | fec_t __iomem *fecp; | 18 | fec_t __iomem *fecp; |
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index da4efbca646e..e36321152d50 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c | |||
@@ -81,16 +81,8 @@ | |||
81 | static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op) | 81 | static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op) |
82 | { | 82 | { |
83 | const struct fs_platform_info *fpi = fep->fpi; | 83 | const struct fs_platform_info *fpi = fep->fpi; |
84 | int i; | ||
85 | |||
86 | W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG); | ||
87 | for (i = 0; i < MAX_CR_CMD_LOOPS; i++) | ||
88 | if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) | ||
89 | return 0; | ||
90 | 84 | ||
91 | printk(KERN_ERR "%s(): Not able to issue CPM command\n", | 85 | return cpm_command(fpi->cp_command, op); |
92 | __FUNCTION__); | ||
93 | return 1; | ||
94 | } | 86 | } |
95 | 87 | ||
96 | static int do_pd_setup(struct fs_enet_private *fep) | 88 | static int do_pd_setup(struct fs_enet_private *fep) |
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index c1fee48517e3..8a311d1e435b 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <asm/8xx_immap.h> | 40 | #include <asm/8xx_immap.h> |
41 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
42 | #include <asm/mpc8xx.h> | 42 | #include <asm/mpc8xx.h> |
43 | #include <asm/commproc.h> | 43 | #include <asm/cpm1.h> |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | 46 | #ifdef CONFIG_PPC_CPM_NEW_BINDING |
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 48f2f3005935..d7ca31945c82 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <asm/8xx_immap.h> | 40 | #include <asm/8xx_immap.h> |
41 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
42 | #include <asm/mpc8xx.h> | 42 | #include <asm/mpc8xx.h> |
43 | #include <asm/commproc.h> | 43 | #include <asm/cpm1.h> |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | 46 | #ifdef CONFIG_PPC_CPM_NEW_BINDING |
@@ -89,21 +89,12 @@ | |||
89 | * Delay to wait for SCC reset command to complete (in us) | 89 | * Delay to wait for SCC reset command to complete (in us) |
90 | */ | 90 | */ |
91 | #define SCC_RESET_DELAY 50 | 91 | #define SCC_RESET_DELAY 50 |
92 | #define MAX_CR_CMD_LOOPS 10000 | ||
93 | 92 | ||
94 | static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op) | 93 | static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op) |
95 | { | 94 | { |
96 | const struct fs_platform_info *fpi = fep->fpi; | 95 | const struct fs_platform_info *fpi = fep->fpi; |
97 | int i; | ||
98 | |||
99 | W16(cpmp, cp_cpcr, fpi->cp_command | CPM_CR_FLG | (op << 8)); | ||
100 | for (i = 0; i < MAX_CR_CMD_LOOPS; i++) | ||
101 | if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) | ||
102 | return 0; | ||
103 | 96 | ||
104 | printk(KERN_ERR "%s(): Not able to issue CPM command\n", | 97 | return cpm_command(fpi->cp_command, op); |
105 | __FUNCTION__); | ||
106 | return 1; | ||
107 | } | 98 | } |
108 | 99 | ||
109 | static int do_pd_setup(struct fs_enet_private *fep) | 100 | static int do_pd_setup(struct fs_enet_private *fep) |
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index b24bd2dfb725..e6c69f77259b 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/mii.h> | 37 | #include <linux/mii.h> |
38 | #include <linux/bitops.h> | 38 | #include <linux/bitops.h> |
39 | #include <linux/workqueue.h> | 39 | #include <linux/workqueue.h> |
40 | #include <linux/of.h> | ||
40 | 41 | ||
41 | #include <asm/processor.h> | 42 | #include <asm/processor.h> |
42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 54b2ba996640..7fe03ce774b1 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
@@ -61,34 +61,12 @@ config ICPLUS_PHY | |||
61 | Currently supports the IP175C PHY. | 61 | Currently supports the IP175C PHY. |
62 | 62 | ||
63 | config FIXED_PHY | 63 | config FIXED_PHY |
64 | tristate "Drivers for PHY emulation on fixed speed/link" | 64 | bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" |
65 | ---help--- | 65 | ---help--- |
66 | Adds the driver to PHY layer to cover the boards that do not have any PHY bound, | 66 | Adds the platform "fixed" MDIO Bus to cover the boards that use |
67 | but with the ability to manipulate the speed/link in software. The relevant MII | 67 | PHYs that are not connected to the real MDIO bus. |
68 | speed/duplex parameters could be effectively handled in a user-specified function. | 68 | |
69 | Currently tested with mpc866ads. | 69 | Currently tested with mpc866ads and mpc8349e-mitx. |
70 | |||
71 | config FIXED_MII_10_FDX | ||
72 | bool "Emulation for 10M Fdx fixed PHY behavior" | ||
73 | depends on FIXED_PHY | ||
74 | |||
75 | config FIXED_MII_100_FDX | ||
76 | bool "Emulation for 100M Fdx fixed PHY behavior" | ||
77 | depends on FIXED_PHY | ||
78 | |||
79 | config FIXED_MII_1000_FDX | ||
80 | bool "Emulation for 1000M Fdx fixed PHY behavior" | ||
81 | depends on FIXED_PHY | ||
82 | |||
83 | config FIXED_MII_AMNT | ||
84 | int "Number of emulated PHYs to allocate " | ||
85 | depends on FIXED_PHY | ||
86 | default "1" | ||
87 | ---help--- | ||
88 | Sometimes it is required to have several independent emulated | ||
89 | PHYs on the bus (in case of multi-eth but phy-less HW for instance). | ||
90 | This control will have specified number allocated for each fixed | ||
91 | PHY type enabled. | ||
92 | 70 | ||
93 | config MDIO_BITBANG | 71 | config MDIO_BITBANG |
94 | tristate "Support for bitbanged MDIO buses" | 72 | tristate "Support for bitbanged MDIO buses" |
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index 56191822fa26..73b6d39ef6b0 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c | |||
@@ -1,362 +1,253 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/net/phy/fixed.c | 2 | * Fixed MDIO bus (MDIO bus emulation with fixed PHYs) |
3 | * | 3 | * |
4 | * Driver for fixed PHYs, when transceiver is able to operate in one fixed mode. | 4 | * Author: Vitaly Bordug <vbordug@ru.mvista.com> |
5 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
5 | * | 6 | * |
6 | * Author: Vitaly Bordug | 7 | * Copyright (c) 2006-2007 MontaVista Software, Inc. |
7 | * | ||
8 | * Copyright (c) 2006 MontaVista Software, Inc. | ||
9 | * | 8 | * |
10 | * This program is free software; you can redistribute it and/or modify it | 9 | * 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 | 10 | * 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 | 11 | * Free Software Foundation; either version 2 of the License, or (at your |
13 | * option) any later version. | 12 | * option) any later version. |
14 | * | ||
15 | */ | 13 | */ |
14 | |||
16 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
17 | #include <linux/string.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/unistd.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/netdevice.h> | ||
25 | #include <linux/etherdevice.h> | ||
26 | #include <linux/skbuff.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/mm.h> | ||
29 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/list.h> | ||
30 | #include <linux/mii.h> | 19 | #include <linux/mii.h> |
31 | #include <linux/ethtool.h> | ||
32 | #include <linux/phy.h> | 20 | #include <linux/phy.h> |
33 | #include <linux/phy_fixed.h> | 21 | #include <linux/phy_fixed.h> |
34 | 22 | ||
35 | #include <asm/io.h> | 23 | #define MII_REGS_NUM 29 |
36 | #include <asm/irq.h> | ||
37 | #include <asm/uaccess.h> | ||
38 | 24 | ||
39 | /* we need to track the allocated pointers in order to free them on exit */ | 25 | struct fixed_mdio_bus { |
40 | static struct fixed_info *fixed_phy_ptrs[CONFIG_FIXED_MII_AMNT*MAX_PHY_AMNT]; | 26 | int irqs[PHY_MAX_ADDR]; |
41 | 27 | struct mii_bus mii_bus; | |
42 | /*----------------------------------------------------------------------------- | 28 | struct list_head phys; |
43 | * If something weird is required to be done with link/speed, | 29 | }; |
44 | * network driver is able to assign a function to implement this. | ||
45 | * May be useful for PHY's that need to be software-driven. | ||
46 | *-----------------------------------------------------------------------------*/ | ||
47 | int fixed_mdio_set_link_update(struct phy_device *phydev, | ||
48 | int (*link_update) (struct net_device *, | ||
49 | struct fixed_phy_status *)) | ||
50 | { | ||
51 | struct fixed_info *fixed; | ||
52 | |||
53 | if (link_update == NULL) | ||
54 | return -EINVAL; | ||
55 | |||
56 | if (phydev) { | ||
57 | if (phydev->bus) { | ||
58 | fixed = phydev->bus->priv; | ||
59 | fixed->link_update = link_update; | ||
60 | return 0; | ||
61 | } | ||
62 | } | ||
63 | return -EINVAL; | ||
64 | } | ||
65 | |||
66 | EXPORT_SYMBOL(fixed_mdio_set_link_update); | ||
67 | 30 | ||
68 | struct fixed_info *fixed_mdio_get_phydev (int phydev_ind) | 31 | struct fixed_phy { |
69 | { | 32 | int id; |
70 | if (phydev_ind >= MAX_PHY_AMNT) | 33 | u16 regs[MII_REGS_NUM]; |
71 | return NULL; | 34 | struct phy_device *phydev; |
72 | return fixed_phy_ptrs[phydev_ind]; | 35 | struct fixed_phy_status status; |
73 | } | 36 | int (*link_update)(struct net_device *, struct fixed_phy_status *); |
37 | struct list_head node; | ||
38 | }; | ||
74 | 39 | ||
75 | EXPORT_SYMBOL(fixed_mdio_get_phydev); | 40 | static struct platform_device *pdev; |
41 | static struct fixed_mdio_bus platform_fmb = { | ||
42 | .phys = LIST_HEAD_INIT(platform_fmb.phys), | ||
43 | }; | ||
76 | 44 | ||
77 | /*----------------------------------------------------------------------------- | 45 | static int fixed_phy_update_regs(struct fixed_phy *fp) |
78 | * This is used for updating internal mii regs from the status | ||
79 | *-----------------------------------------------------------------------------*/ | ||
80 | #if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX) | ||
81 | static int fixed_mdio_update_regs(struct fixed_info *fixed) | ||
82 | { | 46 | { |
83 | u16 *regs = fixed->regs; | 47 | u16 bmsr = BMSR_ANEGCAPABLE; |
84 | u16 bmsr = 0; | ||
85 | u16 bmcr = 0; | 48 | u16 bmcr = 0; |
49 | u16 lpagb = 0; | ||
50 | u16 lpa = 0; | ||
86 | 51 | ||
87 | if (!regs) { | 52 | if (fp->status.duplex) { |
88 | printk(KERN_ERR "%s: regs not set up", __FUNCTION__); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | if (fixed->phy_status.link) | ||
93 | bmsr |= BMSR_LSTATUS; | ||
94 | |||
95 | if (fixed->phy_status.duplex) { | ||
96 | bmcr |= BMCR_FULLDPLX; | 53 | bmcr |= BMCR_FULLDPLX; |
97 | 54 | ||
98 | switch (fixed->phy_status.speed) { | 55 | switch (fp->status.speed) { |
56 | case 1000: | ||
57 | bmsr |= BMSR_ESTATEN; | ||
58 | bmcr |= BMCR_SPEED1000; | ||
59 | lpagb |= LPA_1000FULL; | ||
60 | break; | ||
99 | case 100: | 61 | case 100: |
100 | bmsr |= BMSR_100FULL; | 62 | bmsr |= BMSR_100FULL; |
101 | bmcr |= BMCR_SPEED100; | 63 | bmcr |= BMCR_SPEED100; |
64 | lpa |= LPA_100FULL; | ||
102 | break; | 65 | break; |
103 | |||
104 | case 10: | 66 | case 10: |
105 | bmsr |= BMSR_10FULL; | 67 | bmsr |= BMSR_10FULL; |
68 | lpa |= LPA_10FULL; | ||
106 | break; | 69 | break; |
70 | default: | ||
71 | printk(KERN_WARNING "fixed phy: unknown speed\n"); | ||
72 | return -EINVAL; | ||
107 | } | 73 | } |
108 | } else { | 74 | } else { |
109 | switch (fixed->phy_status.speed) { | 75 | switch (fp->status.speed) { |
76 | case 1000: | ||
77 | bmsr |= BMSR_ESTATEN; | ||
78 | bmcr |= BMCR_SPEED1000; | ||
79 | lpagb |= LPA_1000HALF; | ||
80 | break; | ||
110 | case 100: | 81 | case 100: |
111 | bmsr |= BMSR_100HALF; | 82 | bmsr |= BMSR_100HALF; |
112 | bmcr |= BMCR_SPEED100; | 83 | bmcr |= BMCR_SPEED100; |
84 | lpa |= LPA_100HALF; | ||
113 | break; | 85 | break; |
114 | |||
115 | case 10: | 86 | case 10: |
116 | bmsr |= BMSR_100HALF; | 87 | bmsr |= BMSR_10HALF; |
88 | lpa |= LPA_10HALF; | ||
117 | break; | 89 | break; |
90 | default: | ||
91 | printk(KERN_WARNING "fixed phy: unknown speed\n"); | ||
92 | return -EINVAL; | ||
118 | } | 93 | } |
119 | } | 94 | } |
120 | 95 | ||
121 | regs[MII_BMCR] = bmcr; | 96 | if (fp->status.link) |
122 | regs[MII_BMSR] = bmsr | 0x800; /*we are always capable of 10 hdx */ | 97 | bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE; |
98 | |||
99 | if (fp->status.pause) | ||
100 | lpa |= LPA_PAUSE_CAP; | ||
101 | |||
102 | if (fp->status.asym_pause) | ||
103 | lpa |= LPA_PAUSE_ASYM; | ||
104 | |||
105 | fp->regs[MII_PHYSID1] = fp->id >> 16; | ||
106 | fp->regs[MII_PHYSID2] = fp->id; | ||
107 | |||
108 | fp->regs[MII_BMSR] = bmsr; | ||
109 | fp->regs[MII_BMCR] = bmcr; | ||
110 | fp->regs[MII_LPA] = lpa; | ||
111 | fp->regs[MII_STAT1000] = lpagb; | ||
123 | 112 | ||
124 | return 0; | 113 | return 0; |
125 | } | 114 | } |
126 | 115 | ||
127 | static int fixed_mii_read(struct mii_bus *bus, int phy_id, int location) | 116 | static int fixed_mdio_read(struct mii_bus *bus, int phy_id, int reg_num) |
128 | { | 117 | { |
129 | struct fixed_info *fixed = bus->priv; | 118 | struct fixed_mdio_bus *fmb = container_of(bus, struct fixed_mdio_bus, |
130 | 119 | mii_bus); | |
131 | /* if user has registered link update callback, use it */ | 120 | struct fixed_phy *fp; |
132 | if (fixed->phydev) | 121 | |
133 | if (fixed->phydev->attached_dev) { | 122 | if (reg_num >= MII_REGS_NUM) |
134 | if (fixed->link_update) { | 123 | return -1; |
135 | fixed->link_update(fixed->phydev->attached_dev, | 124 | |
136 | &fixed->phy_status); | 125 | list_for_each_entry(fp, &fmb->phys, node) { |
137 | fixed_mdio_update_regs(fixed); | 126 | if (fp->id == phy_id) { |
127 | /* Issue callback if user registered it. */ | ||
128 | if (fp->link_update) { | ||
129 | fp->link_update(fp->phydev->attached_dev, | ||
130 | &fp->status); | ||
131 | fixed_phy_update_regs(fp); | ||
138 | } | 132 | } |
133 | return fp->regs[reg_num]; | ||
139 | } | 134 | } |
135 | } | ||
140 | 136 | ||
141 | if ((unsigned int)location >= fixed->regs_num) | 137 | return 0xFFFF; |
142 | return -1; | ||
143 | return fixed->regs[location]; | ||
144 | } | 138 | } |
145 | 139 | ||
146 | static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location, | 140 | static int fixed_mdio_write(struct mii_bus *bus, int phy_id, int reg_num, |
147 | u16 val) | 141 | u16 val) |
148 | { | 142 | { |
149 | /* do nothing for now */ | ||
150 | return 0; | 143 | return 0; |
151 | } | 144 | } |
152 | 145 | ||
153 | static int fixed_mii_reset(struct mii_bus *bus) | 146 | /* |
147 | * If something weird is required to be done with link/speed, | ||
148 | * network driver is able to assign a function to implement this. | ||
149 | * May be useful for PHY's that need to be software-driven. | ||
150 | */ | ||
151 | int fixed_phy_set_link_update(struct phy_device *phydev, | ||
152 | int (*link_update)(struct net_device *, | ||
153 | struct fixed_phy_status *)) | ||
154 | { | 154 | { |
155 | /*nothing here - no way/need to reset it */ | 155 | struct fixed_mdio_bus *fmb = &platform_fmb; |
156 | return 0; | 156 | struct fixed_phy *fp; |
157 | } | ||
158 | #endif | ||
159 | 157 | ||
160 | static int fixed_config_aneg(struct phy_device *phydev) | 158 | if (!link_update || !phydev || !phydev->bus) |
161 | { | 159 | return -EINVAL; |
162 | /* :TODO:03/13/2006 09:45:37 PM:: | ||
163 | The full autoneg funcionality can be emulated, | ||
164 | but no need to have anything here for now | ||
165 | */ | ||
166 | return 0; | ||
167 | } | ||
168 | 160 | ||
169 | /*----------------------------------------------------------------------------- | 161 | list_for_each_entry(fp, &fmb->phys, node) { |
170 | * the manual bind will do the magic - with phy_id_mask == 0 | 162 | if (fp->id == phydev->phy_id) { |
171 | * match will never return true... | 163 | fp->link_update = link_update; |
172 | *-----------------------------------------------------------------------------*/ | 164 | fp->phydev = phydev; |
173 | static struct phy_driver fixed_mdio_driver = { | 165 | return 0; |
174 | .name = "Fixed PHY", | 166 | } |
175 | #ifdef CONFIG_FIXED_MII_1000_FDX | 167 | } |
176 | .features = PHY_GBIT_FEATURES, | ||
177 | #else | ||
178 | .features = PHY_BASIC_FEATURES, | ||
179 | #endif | ||
180 | .config_aneg = fixed_config_aneg, | ||
181 | .read_status = genphy_read_status, | ||
182 | .driver = { .owner = THIS_MODULE, }, | ||
183 | }; | ||
184 | 168 | ||
185 | static void fixed_mdio_release(struct device *dev) | 169 | return -ENOENT; |
186 | { | ||
187 | struct phy_device *phydev = container_of(dev, struct phy_device, dev); | ||
188 | struct mii_bus *bus = phydev->bus; | ||
189 | struct fixed_info *fixed = bus->priv; | ||
190 | |||
191 | kfree(phydev); | ||
192 | kfree(bus->dev); | ||
193 | kfree(bus); | ||
194 | kfree(fixed->regs); | ||
195 | kfree(fixed); | ||
196 | } | 170 | } |
171 | EXPORT_SYMBOL_GPL(fixed_phy_set_link_update); | ||
197 | 172 | ||
198 | /*----------------------------------------------------------------------------- | 173 | int fixed_phy_add(unsigned int irq, int phy_id, |
199 | * This func is used to create all the necessary stuff, bind | 174 | struct fixed_phy_status *status) |
200 | * the fixed phy driver and register all it on the mdio_bus_type. | ||
201 | * speed is either 10 or 100 or 1000, duplex is boolean. | ||
202 | * number is used to create multiple fixed PHYs, so that several devices can | ||
203 | * utilize them simultaneously. | ||
204 | * | ||
205 | * The device on mdio bus will look like [bus_id]:[phy_id], | ||
206 | * bus_id = number | ||
207 | * phy_id = speed+duplex. | ||
208 | *-----------------------------------------------------------------------------*/ | ||
209 | #if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX) | ||
210 | struct fixed_info *fixed_mdio_register_device( | ||
211 | int bus_id, int speed, int duplex, u8 phy_id) | ||
212 | { | 175 | { |
213 | struct mii_bus *new_bus; | 176 | int ret; |
214 | struct fixed_info *fixed; | 177 | struct fixed_mdio_bus *fmb = &platform_fmb; |
215 | struct phy_device *phydev; | 178 | struct fixed_phy *fp; |
216 | int err; | ||
217 | 179 | ||
218 | struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); | 180 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); |
181 | if (!fp) | ||
182 | return -ENOMEM; | ||
219 | 183 | ||
220 | if (dev == NULL) | 184 | memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM); |
221 | goto err_dev_alloc; | ||
222 | 185 | ||
223 | new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); | 186 | fmb->irqs[phy_id] = irq; |
224 | 187 | ||
225 | if (new_bus == NULL) | 188 | fp->id = phy_id; |
226 | goto err_bus_alloc; | 189 | fp->status = *status; |
227 | 190 | ||
228 | fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL); | 191 | ret = fixed_phy_update_regs(fp); |
192 | if (ret) | ||
193 | goto err_regs; | ||
229 | 194 | ||
230 | if (fixed == NULL) | 195 | list_add_tail(&fp->node, &fmb->phys); |
231 | goto err_fixed_alloc; | ||
232 | 196 | ||
233 | fixed->regs = kzalloc(MII_REGS_NUM * sizeof(int), GFP_KERNEL); | 197 | return 0; |
234 | if (NULL == fixed->regs) | ||
235 | goto err_fixed_regs_alloc; | ||
236 | 198 | ||
237 | fixed->regs_num = MII_REGS_NUM; | 199 | err_regs: |
238 | fixed->phy_status.speed = speed; | 200 | kfree(fp); |
239 | fixed->phy_status.duplex = duplex; | 201 | return ret; |
240 | fixed->phy_status.link = 1; | 202 | } |
203 | EXPORT_SYMBOL_GPL(fixed_phy_add); | ||
241 | 204 | ||
242 | new_bus->name = "Fixed MII Bus"; | 205 | static int __init fixed_mdio_bus_init(void) |
243 | new_bus->read = &fixed_mii_read; | 206 | { |
244 | new_bus->write = &fixed_mii_write; | 207 | struct fixed_mdio_bus *fmb = &platform_fmb; |
245 | new_bus->reset = &fixed_mii_reset; | 208 | int ret; |
246 | /*set up workspace */ | ||
247 | fixed_mdio_update_regs(fixed); | ||
248 | new_bus->priv = fixed; | ||
249 | 209 | ||
250 | new_bus->dev = dev; | 210 | pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0); |
251 | dev_set_drvdata(dev, new_bus); | 211 | if (!pdev) { |
212 | ret = -ENOMEM; | ||
213 | goto err_pdev; | ||
214 | } | ||
252 | 215 | ||
253 | /* create phy_device and register it on the mdio bus */ | 216 | fmb->mii_bus.id = 0; |
254 | phydev = phy_device_create(new_bus, 0, 0); | 217 | fmb->mii_bus.name = "Fixed MDIO Bus"; |
255 | if (phydev == NULL) | 218 | fmb->mii_bus.dev = &pdev->dev; |
256 | goto err_phy_dev_create; | 219 | fmb->mii_bus.read = &fixed_mdio_read; |
220 | fmb->mii_bus.write = &fixed_mdio_write; | ||
221 | fmb->mii_bus.irq = fmb->irqs; | ||
257 | 222 | ||
258 | /* | 223 | ret = mdiobus_register(&fmb->mii_bus); |
259 | * Put the phydev pointer into the fixed pack so that bus read/write | 224 | if (ret) |
260 | * code could be able to access for instance attached netdev. Well it | 225 | goto err_mdiobus_reg; |
261 | * doesn't have to do so, only in case of utilizing user-specified | ||
262 | * link-update... | ||
263 | */ | ||
264 | 226 | ||
265 | fixed->phydev = phydev; | 227 | return 0; |
266 | phydev->speed = speed; | ||
267 | phydev->duplex = duplex; | ||
268 | 228 | ||
269 | phydev->irq = PHY_IGNORE_INTERRUPT; | 229 | err_mdiobus_reg: |
270 | phydev->dev.bus = &mdio_bus_type; | 230 | platform_device_unregister(pdev); |
231 | err_pdev: | ||
232 | return ret; | ||
233 | } | ||
234 | module_init(fixed_mdio_bus_init); | ||
271 | 235 | ||
272 | snprintf(phydev->dev.bus_id, BUS_ID_SIZE, | 236 | static void __exit fixed_mdio_bus_exit(void) |
273 | PHY_ID_FMT, bus_id, phy_id); | 237 | { |
238 | struct fixed_mdio_bus *fmb = &platform_fmb; | ||
239 | struct fixed_phy *fp; | ||
274 | 240 | ||
275 | phydev->bus = new_bus; | 241 | mdiobus_unregister(&fmb->mii_bus); |
242 | platform_device_unregister(pdev); | ||
276 | 243 | ||
277 | phydev->dev.driver = &fixed_mdio_driver.driver; | 244 | list_for_each_entry(fp, &fmb->phys, node) { |
278 | phydev->dev.release = fixed_mdio_release; | 245 | list_del(&fp->node); |
279 | err = phydev->dev.driver->probe(&phydev->dev); | 246 | kfree(fp); |
280 | if (err < 0) { | ||
281 | printk(KERN_ERR "Phy %s: problems with fixed driver\n", | ||
282 | phydev->dev.bus_id); | ||
283 | goto err_out; | ||
284 | } | ||
285 | err = device_register(&phydev->dev); | ||
286 | if (err) { | ||
287 | printk(KERN_ERR "Phy %s failed to register\n", | ||
288 | phydev->dev.bus_id); | ||
289 | goto err_out; | ||
290 | } | 247 | } |
291 | //phydev->state = PHY_RUNNING; /* make phy go up quick, but in 10Mbit/HDX | ||
292 | return fixed; | ||
293 | |||
294 | err_out: | ||
295 | kfree(phydev); | ||
296 | err_phy_dev_create: | ||
297 | kfree(fixed->regs); | ||
298 | err_fixed_regs_alloc: | ||
299 | kfree(fixed); | ||
300 | err_fixed_alloc: | ||
301 | kfree(new_bus); | ||
302 | err_bus_alloc: | ||
303 | kfree(dev); | ||
304 | err_dev_alloc: | ||
305 | |||
306 | return NULL; | ||
307 | |||
308 | } | 248 | } |
309 | #endif | 249 | module_exit(fixed_mdio_bus_exit); |
310 | 250 | ||
311 | MODULE_DESCRIPTION("Fixed PHY device & driver for PAL"); | 251 | MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)"); |
312 | MODULE_AUTHOR("Vitaly Bordug"); | 252 | MODULE_AUTHOR("Vitaly Bordug"); |
313 | MODULE_LICENSE("GPL"); | 253 | MODULE_LICENSE("GPL"); |
314 | |||
315 | static int __init fixed_init(void) | ||
316 | { | ||
317 | int cnt = 0; | ||
318 | int i; | ||
319 | /* register on the bus... Not expected to be matched | ||
320 | * with anything there... | ||
321 | * | ||
322 | */ | ||
323 | phy_driver_register(&fixed_mdio_driver); | ||
324 | |||
325 | /* We will create several mdio devices here, and will bound the upper | ||
326 | * driver to them. | ||
327 | * | ||
328 | * Then the external software can lookup the phy bus by searching | ||
329 | * for 0:101, to be connected to the virtual 100M Fdx phy. | ||
330 | * | ||
331 | * In case several virtual PHYs required, the bus_id will be in form | ||
332 | * [num]:[duplex]+[speed], which make it able even to define | ||
333 | * driver-specific link control callback, if for instance PHY is | ||
334 | * completely SW-driven. | ||
335 | */ | ||
336 | for (i=1; i <= CONFIG_FIXED_MII_AMNT; i++) { | ||
337 | #ifdef CONFIG_FIXED_MII_1000_FDX | ||
338 | fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(0, 1000, 1, i); | ||
339 | #endif | ||
340 | #ifdef CONFIG_FIXED_MII_100_FDX | ||
341 | fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(1, 100, 1, i); | ||
342 | #endif | ||
343 | #ifdef CONFIG_FIXED_MII_10_FDX | ||
344 | fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(2, 10, 1, i); | ||
345 | #endif | ||
346 | } | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static void __exit fixed_exit(void) | ||
352 | { | ||
353 | int i; | ||
354 | |||
355 | phy_driver_unregister(&fixed_mdio_driver); | ||
356 | for (i=0; i < MAX_PHY_AMNT; i++) | ||
357 | if ( fixed_phy_ptrs[i] ) | ||
358 | device_unregister(&fixed_phy_ptrs[i]->phydev->dev); | ||
359 | } | ||
360 | |||
361 | module_init(fixed_init); | ||
362 | module_exit(fixed_exit); | ||
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 0a42bf517465..055af081e027 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c | |||
@@ -58,11 +58,11 @@ static inline struct device *ctodev(struct gelic_net_card *card) | |||
58 | { | 58 | { |
59 | return &card->dev->core; | 59 | return &card->dev->core; |
60 | } | 60 | } |
61 | static inline unsigned int bus_id(struct gelic_net_card *card) | 61 | static inline u64 bus_id(struct gelic_net_card *card) |
62 | { | 62 | { |
63 | return card->dev->bus_id; | 63 | return card->dev->bus_id; |
64 | } | 64 | } |
65 | static inline unsigned int dev_id(struct gelic_net_card *card) | 65 | static inline u64 dev_id(struct gelic_net_card *card) |
66 | { | 66 | { |
67 | return card->dev->dev_id; | 67 | return card->dev->dev_id; |
68 | } | 68 | } |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 73d6ac9406b3..4ffd8739f8b7 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -3819,6 +3819,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3819 | int err, ucc_num, max_speed = 0; | 3819 | int err, ucc_num, max_speed = 0; |
3820 | const phandle *ph; | 3820 | const phandle *ph; |
3821 | const unsigned int *prop; | 3821 | const unsigned int *prop; |
3822 | const char *sprop; | ||
3822 | const void *mac_addr; | 3823 | const void *mac_addr; |
3823 | phy_interface_t phy_interface; | 3824 | phy_interface_t phy_interface; |
3824 | static const int enet_to_speed[] = { | 3825 | static const int enet_to_speed[] = { |
@@ -3851,10 +3852,56 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3851 | 3852 | ||
3852 | ug_info->uf_info.ucc_num = ucc_num; | 3853 | ug_info->uf_info.ucc_num = ucc_num; |
3853 | 3854 | ||
3854 | prop = of_get_property(np, "rx-clock", NULL); | 3855 | sprop = of_get_property(np, "rx-clock-name", NULL); |
3855 | ug_info->uf_info.rx_clock = *prop; | 3856 | if (sprop) { |
3856 | prop = of_get_property(np, "tx-clock", NULL); | 3857 | ug_info->uf_info.rx_clock = qe_clock_source(sprop); |
3857 | ug_info->uf_info.tx_clock = *prop; | 3858 | if ((ug_info->uf_info.rx_clock < QE_CLK_NONE) || |
3859 | (ug_info->uf_info.rx_clock > QE_CLK24)) { | ||
3860 | printk(KERN_ERR | ||
3861 | "ucc_geth: invalid rx-clock-name property\n"); | ||
3862 | return -EINVAL; | ||
3863 | } | ||
3864 | } else { | ||
3865 | prop = of_get_property(np, "rx-clock", NULL); | ||
3866 | if (!prop) { | ||
3867 | /* If both rx-clock-name and rx-clock are missing, | ||
3868 | we want to tell people to use rx-clock-name. */ | ||
3869 | printk(KERN_ERR | ||
3870 | "ucc_geth: missing rx-clock-name property\n"); | ||
3871 | return -EINVAL; | ||
3872 | } | ||
3873 | if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) { | ||
3874 | printk(KERN_ERR | ||
3875 | "ucc_geth: invalid rx-clock propperty\n"); | ||
3876 | return -EINVAL; | ||
3877 | } | ||
3878 | ug_info->uf_info.rx_clock = *prop; | ||
3879 | } | ||
3880 | |||
3881 | sprop = of_get_property(np, "tx-clock-name", NULL); | ||
3882 | if (sprop) { | ||
3883 | ug_info->uf_info.tx_clock = qe_clock_source(sprop); | ||
3884 | if ((ug_info->uf_info.tx_clock < QE_CLK_NONE) || | ||
3885 | (ug_info->uf_info.tx_clock > QE_CLK24)) { | ||
3886 | printk(KERN_ERR | ||
3887 | "ucc_geth: invalid tx-clock-name property\n"); | ||
3888 | return -EINVAL; | ||
3889 | } | ||
3890 | } else { | ||
3891 | prop = of_get_property(np, "rx-clock", NULL); | ||
3892 | if (!prop) { | ||
3893 | printk(KERN_ERR | ||
3894 | "ucc_geth: mising tx-clock-name property\n"); | ||
3895 | return -EINVAL; | ||
3896 | } | ||
3897 | if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) { | ||
3898 | printk(KERN_ERR | ||
3899 | "ucc_geth: invalid tx-clock property\n"); | ||
3900 | return -EINVAL; | ||
3901 | } | ||
3902 | ug_info->uf_info.tx_clock = *prop; | ||
3903 | } | ||
3904 | |||
3858 | err = of_address_to_resource(np, 0, &res); | 3905 | err = of_address_to_resource(np, 0, &res); |
3859 | if (err) | 3906 | if (err) |
3860 | return -EINVAL; | 3907 | return -EINVAL; |
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index df884f0ad8e5..e3ba14a19915 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c | |||
@@ -256,6 +256,9 @@ static struct of_device_id uec_mdio_match[] = { | |||
256 | .type = "mdio", | 256 | .type = "mdio", |
257 | .compatible = "ucc_geth_phy", | 257 | .compatible = "ucc_geth_phy", |
258 | }, | 258 | }, |
259 | { | ||
260 | .compatible = "fsl,ucc-mdio", | ||
261 | }, | ||
259 | {}, | 262 | {}, |
260 | }; | 263 | }; |
261 | 264 | ||
diff --git a/drivers/of/base.c b/drivers/of/base.c index 9377f3bc410a..b306fef1ac41 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -273,3 +273,61 @@ struct device_node *of_find_compatible_node(struct device_node *from, | |||
273 | return np; | 273 | return np; |
274 | } | 274 | } |
275 | EXPORT_SYMBOL(of_find_compatible_node); | 275 | EXPORT_SYMBOL(of_find_compatible_node); |
276 | |||
277 | /** | ||
278 | * of_match_node - Tell if an device_node has a matching of_match structure | ||
279 | * @matches: array of of device match structures to search in | ||
280 | * @node: the of device structure to match against | ||
281 | * | ||
282 | * Low level utility function used by device matching. | ||
283 | */ | ||
284 | const struct of_device_id *of_match_node(const struct of_device_id *matches, | ||
285 | const struct device_node *node) | ||
286 | { | ||
287 | while (matches->name[0] || matches->type[0] || matches->compatible[0]) { | ||
288 | int match = 1; | ||
289 | if (matches->name[0]) | ||
290 | match &= node->name | ||
291 | && !strcmp(matches->name, node->name); | ||
292 | if (matches->type[0]) | ||
293 | match &= node->type | ||
294 | && !strcmp(matches->type, node->type); | ||
295 | if (matches->compatible[0]) | ||
296 | match &= of_device_is_compatible(node, | ||
297 | matches->compatible); | ||
298 | if (match) | ||
299 | return matches; | ||
300 | matches++; | ||
301 | } | ||
302 | return NULL; | ||
303 | } | ||
304 | EXPORT_SYMBOL(of_match_node); | ||
305 | |||
306 | /** | ||
307 | * of_find_matching_node - Find a node based on an of_device_id match | ||
308 | * table. | ||
309 | * @from: The node to start searching from or NULL, the node | ||
310 | * you pass will not be searched, only the next one | ||
311 | * will; typically, you pass what the previous call | ||
312 | * returned. of_node_put() will be called on it | ||
313 | * @matches: array of of device match structures to search in | ||
314 | * | ||
315 | * Returns a node pointer with refcount incremented, use | ||
316 | * of_node_put() on it when done. | ||
317 | */ | ||
318 | struct device_node *of_find_matching_node(struct device_node *from, | ||
319 | const struct of_device_id *matches) | ||
320 | { | ||
321 | struct device_node *np; | ||
322 | |||
323 | read_lock(&devtree_lock); | ||
324 | np = from ? from->allnext : allnodes; | ||
325 | for (; np; np = np->allnext) { | ||
326 | if (of_match_node(matches, np) && of_node_get(np)) | ||
327 | break; | ||
328 | } | ||
329 | of_node_put(from); | ||
330 | read_unlock(&devtree_lock); | ||
331 | return np; | ||
332 | } | ||
333 | EXPORT_SYMBOL(of_find_matching_node); | ||
diff --git a/drivers/of/device.c b/drivers/of/device.c index 6245f060fb77..29681c4b700b 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c | |||
@@ -10,35 +10,6 @@ | |||
10 | #include <asm/errno.h> | 10 | #include <asm/errno.h> |
11 | 11 | ||
12 | /** | 12 | /** |
13 | * of_match_node - Tell if an device_node has a matching of_match structure | ||
14 | * @ids: array of of device match structures to search in | ||
15 | * @node: the of device structure to match against | ||
16 | * | ||
17 | * Low level utility function used by device matching. | ||
18 | */ | ||
19 | const struct of_device_id *of_match_node(const struct of_device_id *matches, | ||
20 | const struct device_node *node) | ||
21 | { | ||
22 | while (matches->name[0] || matches->type[0] || matches->compatible[0]) { | ||
23 | int match = 1; | ||
24 | if (matches->name[0]) | ||
25 | match &= node->name | ||
26 | && !strcmp(matches->name, node->name); | ||
27 | if (matches->type[0]) | ||
28 | match &= node->type | ||
29 | && !strcmp(matches->type, node->type); | ||
30 | if (matches->compatible[0]) | ||
31 | match &= of_device_is_compatible(node, | ||
32 | matches->compatible); | ||
33 | if (match) | ||
34 | return matches; | ||
35 | matches++; | ||
36 | } | ||
37 | return NULL; | ||
38 | } | ||
39 | EXPORT_SYMBOL(of_match_node); | ||
40 | |||
41 | /** | ||
42 | * of_match_device - Tell if an of_device structure has a matching | 13 | * of_match_device - Tell if an of_device structure has a matching |
43 | * of_match structure | 14 | * of_match structure |
44 | * @ids: array of of device match structures to search in | 15 | * @ids: array of of device match structures to search in |
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 555055650733..f697f3d728eb 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -32,7 +32,7 @@ obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o | |||
32 | obj-$(CONFIG_PARISC) += setup-bus.o | 32 | obj-$(CONFIG_PARISC) += setup-bus.o |
33 | obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o | 33 | obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o |
34 | obj-$(CONFIG_PPC32) += setup-irq.o | 34 | obj-$(CONFIG_PPC32) += setup-irq.o |
35 | obj-$(CONFIG_PPC64) += setup-bus.o | 35 | obj-$(CONFIG_PPC) += setup-bus.o |
36 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o | 36 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o |
37 | obj-$(CONFIG_X86_VISWS) += setup-irq.o | 37 | obj-$(CONFIG_X86_VISWS) += setup-irq.o |
38 | 38 | ||
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index b169b0e2647f..191954bc8e5b 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
@@ -155,7 +155,7 @@ static void dlpar_pci_add_bus(struct device_node *dn) | |||
155 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | 155 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) |
156 | of_scan_pci_bridge(dn, dev); | 156 | of_scan_pci_bridge(dn, dev); |
157 | 157 | ||
158 | pcibios_fixup_new_pci_devices(dev->subordinate,0); | 158 | pcibios_fixup_new_pci_devices(dev->subordinate); |
159 | 159 | ||
160 | /* Claim new bus resources */ | 160 | /* Claim new bus resources */ |
161 | pcibios_claim_one_bus(dev->bus); | 161 | pcibios_claim_one_bus(dev->bus); |
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile index 1f5a2d33bf5b..ccea15c11c19 100644 --- a/drivers/ps3/Makefile +++ b/drivers/ps3/Makefile | |||
@@ -4,3 +4,4 @@ ps3av_mod-objs += ps3av.o ps3av_cmd.o | |||
4 | obj-$(CONFIG_PPC_PS3) += sys-manager-core.o | 4 | obj-$(CONFIG_PPC_PS3) += sys-manager-core.o |
5 | obj-$(CONFIG_PS3_SYS_MANAGER) += ps3-sys-manager.o | 5 | obj-$(CONFIG_PS3_SYS_MANAGER) += ps3-sys-manager.o |
6 | obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o | 6 | obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o |
7 | obj-$(CONFIG_PS3_LPM) += ps3-lpm.o | ||
diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c new file mode 100644 index 000000000000..4c066545d176 --- /dev/null +++ b/drivers/ps3/ps3-lpm.c | |||
@@ -0,0 +1,1248 @@ | |||
1 | /* | ||
2 | * PS3 Logical Performance Monitor. | ||
3 | * | ||
4 | * Copyright (C) 2007 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2007 Sony Corp. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/uaccess.h> | ||
25 | #include <asm/ps3.h> | ||
26 | #include <asm/lv1call.h> | ||
27 | #include <asm/cell-pmu.h> | ||
28 | |||
29 | |||
30 | /* BOOKMARK tag macros */ | ||
31 | #define PS3_PM_BOOKMARK_START 0x8000000000000000ULL | ||
32 | #define PS3_PM_BOOKMARK_STOP 0x4000000000000000ULL | ||
33 | #define PS3_PM_BOOKMARK_TAG_KERNEL 0x1000000000000000ULL | ||
34 | #define PS3_PM_BOOKMARK_TAG_USER 0x3000000000000000ULL | ||
35 | #define PS3_PM_BOOKMARK_TAG_MASK_HI 0xF000000000000000ULL | ||
36 | #define PS3_PM_BOOKMARK_TAG_MASK_LO 0x0F00000000000000ULL | ||
37 | |||
38 | /* CBE PM CONTROL register macros */ | ||
39 | #define PS3_PM_CONTROL_PPU_TH0_BOOKMARK 0x00001000 | ||
40 | #define PS3_PM_CONTROL_PPU_TH1_BOOKMARK 0x00000800 | ||
41 | #define PS3_PM_CONTROL_PPU_COUNT_MODE_MASK 0x000C0000 | ||
42 | #define PS3_PM_CONTROL_PPU_COUNT_MODE_PROBLEM 0x00080000 | ||
43 | #define PS3_WRITE_PM_MASK 0xFFFFFFFFFFFFFFFFULL | ||
44 | |||
45 | /* CBE PM START STOP register macros */ | ||
46 | #define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START 0x02000000 | ||
47 | #define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START 0x01000000 | ||
48 | #define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP 0x00020000 | ||
49 | #define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP 0x00010000 | ||
50 | #define PS3_PM_START_STOP_START_MASK 0xFF000000 | ||
51 | #define PS3_PM_START_STOP_STOP_MASK 0x00FF0000 | ||
52 | |||
53 | /* CBE PM COUNTER register macres */ | ||
54 | #define PS3_PM_COUNTER_MASK_HI 0xFFFFFFFF00000000ULL | ||
55 | #define PS3_PM_COUNTER_MASK_LO 0x00000000FFFFFFFFULL | ||
56 | |||
57 | /* BASE SIGNAL GROUP NUMBER macros */ | ||
58 | #define PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER 0 | ||
59 | #define PM_ISLAND2_SIGNAL_GROUP_NUMBER1 6 | ||
60 | #define PM_ISLAND2_SIGNAL_GROUP_NUMBER2 7 | ||
61 | #define PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER 7 | ||
62 | #define PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER 15 | ||
63 | #define PM_SPU_TRIGGER_SIGNAL_GROUP_NUMBER 17 | ||
64 | #define PM_SPU_EVENT_SIGNAL_GROUP_NUMBER 18 | ||
65 | #define PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER 18 | ||
66 | #define PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER 24 | ||
67 | #define PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER 49 | ||
68 | #define PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER 52 | ||
69 | #define PM_SIG_GROUP_SPU 41 | ||
70 | #define PM_SIG_GROUP_SPU_TRIGGER 42 | ||
71 | #define PM_SIG_GROUP_SPU_EVENT 43 | ||
72 | #define PM_SIG_GROUP_MFC_MAX 60 | ||
73 | |||
74 | /** | ||
75 | * struct ps3_lpm_shadow_regs - Performance monitor shadow registers. | ||
76 | * | ||
77 | * @pm_control: Shadow of the processor's pm_control register. | ||
78 | * @pm_start_stop: Shadow of the processor's pm_start_stop register. | ||
79 | * @pm_interval: Shadow of the processor's pm_interval register. | ||
80 | * @group_control: Shadow of the processor's group_control register. | ||
81 | * @debug_bus_control: Shadow of the processor's debug_bus_control register. | ||
82 | * | ||
83 | * The logical performance monitor provides a write-only interface to | ||
84 | * these processor registers. These shadow variables cache the processor | ||
85 | * register values for reading. | ||
86 | * | ||
87 | * The initial value of the shadow registers at lpm creation is | ||
88 | * PS3_LPM_SHADOW_REG_INIT. | ||
89 | */ | ||
90 | |||
91 | struct ps3_lpm_shadow_regs { | ||
92 | u64 pm_control; | ||
93 | u64 pm_start_stop; | ||
94 | u64 pm_interval; | ||
95 | u64 group_control; | ||
96 | u64 debug_bus_control; | ||
97 | }; | ||
98 | |||
99 | #define PS3_LPM_SHADOW_REG_INIT 0xFFFFFFFF00000000ULL | ||
100 | |||
101 | /** | ||
102 | * struct ps3_lpm_priv - Private lpm device data. | ||
103 | * | ||
104 | * @open: An atomic variable indicating the lpm driver has been opened. | ||
105 | * @rights: The lpm rigths granted by the system policy module. A logical | ||
106 | * OR of enum ps3_lpm_rights. | ||
107 | * @node_id: The node id of a BE prosessor whose performance monitor this | ||
108 | * lpar has the right to use. | ||
109 | * @pu_id: The lv1 id of the logical PU. | ||
110 | * @lpm_id: The lv1 id of this lpm instance. | ||
111 | * @outlet_id: The outlet created by lv1 for this lpm instance. | ||
112 | * @tb_count: The number of bytes of data held in the lv1 trace buffer. | ||
113 | * @tb_cache: Kernel buffer to receive the data from the lv1 trace buffer. | ||
114 | * Must be 128 byte aligned. | ||
115 | * @tb_cache_size: Size of the kernel @tb_cache buffer. Must be 128 byte | ||
116 | * aligned. | ||
117 | * @tb_cache_internal: An unaligned buffer allocated by this driver to be | ||
118 | * used for the trace buffer cache when ps3_lpm_open() is called with a | ||
119 | * NULL tb_cache argument. Otherwise unused. | ||
120 | * @shadow: Processor register shadow of type struct ps3_lpm_shadow_regs. | ||
121 | * @sbd: The struct ps3_system_bus_device attached to this driver. | ||
122 | * | ||
123 | * The trace buffer is a buffer allocated and used internally to the lv1 | ||
124 | * hypervisor to collect trace data. The trace buffer cache is a guest | ||
125 | * buffer that accepts the trace data from the trace buffer. | ||
126 | */ | ||
127 | |||
128 | struct ps3_lpm_priv { | ||
129 | atomic_t open; | ||
130 | u64 rights; | ||
131 | u64 node_id; | ||
132 | u64 pu_id; | ||
133 | u64 lpm_id; | ||
134 | u64 outlet_id; | ||
135 | u64 tb_count; | ||
136 | void *tb_cache; | ||
137 | u64 tb_cache_size; | ||
138 | void *tb_cache_internal; | ||
139 | struct ps3_lpm_shadow_regs shadow; | ||
140 | struct ps3_system_bus_device *sbd; | ||
141 | }; | ||
142 | |||
143 | enum { | ||
144 | PS3_LPM_DEFAULT_TB_CACHE_SIZE = 0x4000, | ||
145 | }; | ||
146 | |||
147 | /** | ||
148 | * lpm_priv - Static instance of the lpm data. | ||
149 | * | ||
150 | * Since the exported routines don't support the notion of a device | ||
151 | * instance we need to hold the instance in this static variable | ||
152 | * and then only allow at most one instance at a time to be created. | ||
153 | */ | ||
154 | |||
155 | static struct ps3_lpm_priv *lpm_priv; | ||
156 | |||
157 | static struct device *sbd_core(void) | ||
158 | { | ||
159 | BUG_ON(!lpm_priv || !lpm_priv->sbd); | ||
160 | return &lpm_priv->sbd->core; | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * use_start_stop_bookmark - Enable the PPU bookmark trace. | ||
165 | * | ||
166 | * And it enables PPU bookmark triggers ONLY if the other triggers are not set. | ||
167 | * The start/stop bookmarks are inserted at ps3_enable_pm() and ps3_disable_pm() | ||
168 | * to start/stop LPM. | ||
169 | * | ||
170 | * Used to get good quality of the performance counter. | ||
171 | */ | ||
172 | |||
173 | enum {use_start_stop_bookmark = 1,}; | ||
174 | |||
175 | void ps3_set_bookmark(u64 bookmark) | ||
176 | { | ||
177 | /* | ||
178 | * As per the PPE book IV, to avoid bookmark loss there must | ||
179 | * not be a traced branch within 10 cycles of setting the | ||
180 | * SPRN_BKMK register. The actual text is unclear if 'within' | ||
181 | * includes cycles before the call. | ||
182 | */ | ||
183 | |||
184 | asm volatile("or 29, 29, 29;"); /* db10cyc */ | ||
185 | mtspr(SPRN_BKMK, bookmark); | ||
186 | asm volatile("or 29, 29, 29;"); /* db10cyc */ | ||
187 | } | ||
188 | EXPORT_SYMBOL_GPL(ps3_set_bookmark); | ||
189 | |||
190 | void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id) | ||
191 | { | ||
192 | u64 bookmark; | ||
193 | |||
194 | bookmark = (get_tb() & 0x00000000FFFFFFFFULL) | | ||
195 | PS3_PM_BOOKMARK_TAG_KERNEL; | ||
196 | bookmark = ((tag << 56) & PS3_PM_BOOKMARK_TAG_MASK_LO) | | ||
197 | (incident << 48) | (th_id << 32) | bookmark; | ||
198 | ps3_set_bookmark(bookmark); | ||
199 | } | ||
200 | EXPORT_SYMBOL_GPL(ps3_set_pm_bookmark); | ||
201 | |||
202 | /** | ||
203 | * ps3_read_phys_ctr - Read physical counter registers. | ||
204 | * | ||
205 | * Each physical counter can act as one 32 bit counter or as two 16 bit | ||
206 | * counters. | ||
207 | */ | ||
208 | |||
209 | u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr) | ||
210 | { | ||
211 | int result; | ||
212 | u64 counter0415; | ||
213 | u64 counter2637; | ||
214 | |||
215 | if (phys_ctr >= NR_PHYS_CTRS) { | ||
216 | dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, | ||
217 | __LINE__, phys_ctr); | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | result = lv1_set_lpm_counter(lpm_priv->lpm_id, 0, 0, 0, 0, &counter0415, | ||
222 | &counter2637); | ||
223 | if (result) { | ||
224 | dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: " | ||
225 | "phys_ctr %u, %s\n", __func__, __LINE__, phys_ctr, | ||
226 | ps3_result(result)); | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | switch (phys_ctr) { | ||
231 | case 0: | ||
232 | return counter0415 >> 32; | ||
233 | case 1: | ||
234 | return counter0415 & PS3_PM_COUNTER_MASK_LO; | ||
235 | case 2: | ||
236 | return counter2637 >> 32; | ||
237 | case 3: | ||
238 | return counter2637 & PS3_PM_COUNTER_MASK_LO; | ||
239 | default: | ||
240 | BUG(); | ||
241 | } | ||
242 | return 0; | ||
243 | } | ||
244 | EXPORT_SYMBOL_GPL(ps3_read_phys_ctr); | ||
245 | |||
246 | /** | ||
247 | * ps3_write_phys_ctr - Write physical counter registers. | ||
248 | * | ||
249 | * Each physical counter can act as one 32 bit counter or as two 16 bit | ||
250 | * counters. | ||
251 | */ | ||
252 | |||
253 | void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val) | ||
254 | { | ||
255 | u64 counter0415; | ||
256 | u64 counter0415_mask; | ||
257 | u64 counter2637; | ||
258 | u64 counter2637_mask; | ||
259 | int result; | ||
260 | |||
261 | if (phys_ctr >= NR_PHYS_CTRS) { | ||
262 | dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, | ||
263 | __LINE__, phys_ctr); | ||
264 | return; | ||
265 | } | ||
266 | |||
267 | switch (phys_ctr) { | ||
268 | case 0: | ||
269 | counter0415 = (u64)val << 32; | ||
270 | counter0415_mask = PS3_PM_COUNTER_MASK_HI; | ||
271 | counter2637 = 0x0; | ||
272 | counter2637_mask = 0x0; | ||
273 | break; | ||
274 | case 1: | ||
275 | counter0415 = (u64)val; | ||
276 | counter0415_mask = PS3_PM_COUNTER_MASK_LO; | ||
277 | counter2637 = 0x0; | ||
278 | counter2637_mask = 0x0; | ||
279 | break; | ||
280 | case 2: | ||
281 | counter0415 = 0x0; | ||
282 | counter0415_mask = 0x0; | ||
283 | counter2637 = (u64)val << 32; | ||
284 | counter2637_mask = PS3_PM_COUNTER_MASK_HI; | ||
285 | break; | ||
286 | case 3: | ||
287 | counter0415 = 0x0; | ||
288 | counter0415_mask = 0x0; | ||
289 | counter2637 = (u64)val; | ||
290 | counter2637_mask = PS3_PM_COUNTER_MASK_LO; | ||
291 | break; | ||
292 | default: | ||
293 | BUG(); | ||
294 | } | ||
295 | |||
296 | result = lv1_set_lpm_counter(lpm_priv->lpm_id, | ||
297 | counter0415, counter0415_mask, | ||
298 | counter2637, counter2637_mask, | ||
299 | &counter0415, &counter2637); | ||
300 | if (result) | ||
301 | dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: " | ||
302 | "phys_ctr %u, val %u, %s\n", __func__, __LINE__, | ||
303 | phys_ctr, val, ps3_result(result)); | ||
304 | } | ||
305 | EXPORT_SYMBOL_GPL(ps3_write_phys_ctr); | ||
306 | |||
307 | /** | ||
308 | * ps3_read_ctr - Read counter. | ||
309 | * | ||
310 | * Read 16 or 32 bits depending on the current size of the counter. | ||
311 | * Counters 4, 5, 6 & 7 are always 16 bit. | ||
312 | */ | ||
313 | |||
314 | u32 ps3_read_ctr(u32 cpu, u32 ctr) | ||
315 | { | ||
316 | u32 val; | ||
317 | u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1); | ||
318 | |||
319 | val = ps3_read_phys_ctr(cpu, phys_ctr); | ||
320 | |||
321 | if (ps3_get_ctr_size(cpu, phys_ctr) == 16) | ||
322 | val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff); | ||
323 | |||
324 | return val; | ||
325 | } | ||
326 | EXPORT_SYMBOL_GPL(ps3_read_ctr); | ||
327 | |||
328 | /** | ||
329 | * ps3_write_ctr - Write counter. | ||
330 | * | ||
331 | * Write 16 or 32 bits depending on the current size of the counter. | ||
332 | * Counters 4, 5, 6 & 7 are always 16 bit. | ||
333 | */ | ||
334 | |||
335 | void ps3_write_ctr(u32 cpu, u32 ctr, u32 val) | ||
336 | { | ||
337 | u32 phys_ctr; | ||
338 | u32 phys_val; | ||
339 | |||
340 | phys_ctr = ctr & (NR_PHYS_CTRS - 1); | ||
341 | |||
342 | if (ps3_get_ctr_size(cpu, phys_ctr) == 16) { | ||
343 | phys_val = ps3_read_phys_ctr(cpu, phys_ctr); | ||
344 | |||
345 | if (ctr < NR_PHYS_CTRS) | ||
346 | val = (val << 16) | (phys_val & 0xffff); | ||
347 | else | ||
348 | val = (val & 0xffff) | (phys_val & 0xffff0000); | ||
349 | } | ||
350 | |||
351 | ps3_write_phys_ctr(cpu, phys_ctr, val); | ||
352 | } | ||
353 | EXPORT_SYMBOL_GPL(ps3_write_ctr); | ||
354 | |||
355 | /** | ||
356 | * ps3_read_pm07_control - Read counter control registers. | ||
357 | * | ||
358 | * Each logical counter has a corresponding control register. | ||
359 | */ | ||
360 | |||
361 | u32 ps3_read_pm07_control(u32 cpu, u32 ctr) | ||
362 | { | ||
363 | return 0; | ||
364 | } | ||
365 | EXPORT_SYMBOL_GPL(ps3_read_pm07_control); | ||
366 | |||
367 | /** | ||
368 | * ps3_write_pm07_control - Write counter control registers. | ||
369 | * | ||
370 | * Each logical counter has a corresponding control register. | ||
371 | */ | ||
372 | |||
373 | void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val) | ||
374 | { | ||
375 | int result; | ||
376 | static const u64 mask = 0xFFFFFFFFFFFFFFFFULL; | ||
377 | u64 old_value; | ||
378 | |||
379 | if (ctr >= NR_CTRS) { | ||
380 | dev_dbg(sbd_core(), "%s:%u: ctr too big: %u\n", __func__, | ||
381 | __LINE__, ctr); | ||
382 | return; | ||
383 | } | ||
384 | |||
385 | result = lv1_set_lpm_counter_control(lpm_priv->lpm_id, ctr, val, mask, | ||
386 | &old_value); | ||
387 | if (result) | ||
388 | dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter_control " | ||
389 | "failed: ctr %u, %s\n", __func__, __LINE__, ctr, | ||
390 | ps3_result(result)); | ||
391 | } | ||
392 | EXPORT_SYMBOL_GPL(ps3_write_pm07_control); | ||
393 | |||
394 | /** | ||
395 | * ps3_read_pm - Read Other LPM control registers. | ||
396 | */ | ||
397 | |||
398 | u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg) | ||
399 | { | ||
400 | int result = 0; | ||
401 | u64 val = 0; | ||
402 | |||
403 | switch (reg) { | ||
404 | case pm_control: | ||
405 | return lpm_priv->shadow.pm_control; | ||
406 | case trace_address: | ||
407 | return CBE_PM_TRACE_BUF_EMPTY; | ||
408 | case pm_start_stop: | ||
409 | return lpm_priv->shadow.pm_start_stop; | ||
410 | case pm_interval: | ||
411 | return lpm_priv->shadow.pm_interval; | ||
412 | case group_control: | ||
413 | return lpm_priv->shadow.group_control; | ||
414 | case debug_bus_control: | ||
415 | return lpm_priv->shadow.debug_bus_control; | ||
416 | case pm_status: | ||
417 | result = lv1_get_lpm_interrupt_status(lpm_priv->lpm_id, | ||
418 | &val); | ||
419 | if (result) { | ||
420 | val = 0; | ||
421 | dev_dbg(sbd_core(), "%s:%u: lv1 get_lpm_status failed: " | ||
422 | "reg %u, %s\n", __func__, __LINE__, reg, | ||
423 | ps3_result(result)); | ||
424 | } | ||
425 | return (u32)val; | ||
426 | case ext_tr_timer: | ||
427 | return 0; | ||
428 | default: | ||
429 | dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__, | ||
430 | __LINE__, reg); | ||
431 | BUG(); | ||
432 | break; | ||
433 | } | ||
434 | |||
435 | return 0; | ||
436 | } | ||
437 | EXPORT_SYMBOL_GPL(ps3_read_pm); | ||
438 | |||
439 | /** | ||
440 | * ps3_write_pm - Write Other LPM control registers. | ||
441 | */ | ||
442 | |||
443 | void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val) | ||
444 | { | ||
445 | int result = 0; | ||
446 | u64 dummy; | ||
447 | |||
448 | switch (reg) { | ||
449 | case group_control: | ||
450 | if (val != lpm_priv->shadow.group_control) | ||
451 | result = lv1_set_lpm_group_control(lpm_priv->lpm_id, | ||
452 | val, | ||
453 | PS3_WRITE_PM_MASK, | ||
454 | &dummy); | ||
455 | lpm_priv->shadow.group_control = val; | ||
456 | break; | ||
457 | case debug_bus_control: | ||
458 | if (val != lpm_priv->shadow.debug_bus_control) | ||
459 | result = lv1_set_lpm_debug_bus_control(lpm_priv->lpm_id, | ||
460 | val, | ||
461 | PS3_WRITE_PM_MASK, | ||
462 | &dummy); | ||
463 | lpm_priv->shadow.debug_bus_control = val; | ||
464 | break; | ||
465 | case pm_control: | ||
466 | if (use_start_stop_bookmark) | ||
467 | val |= (PS3_PM_CONTROL_PPU_TH0_BOOKMARK | | ||
468 | PS3_PM_CONTROL_PPU_TH1_BOOKMARK); | ||
469 | if (val != lpm_priv->shadow.pm_control) | ||
470 | result = lv1_set_lpm_general_control(lpm_priv->lpm_id, | ||
471 | val, | ||
472 | PS3_WRITE_PM_MASK, | ||
473 | 0, 0, &dummy, | ||
474 | &dummy); | ||
475 | lpm_priv->shadow.pm_control = val; | ||
476 | break; | ||
477 | case pm_interval: | ||
478 | if (val != lpm_priv->shadow.pm_interval) | ||
479 | result = lv1_set_lpm_interval(lpm_priv->lpm_id, val, | ||
480 | PS3_WRITE_PM_MASK, &dummy); | ||
481 | lpm_priv->shadow.pm_interval = val; | ||
482 | break; | ||
483 | case pm_start_stop: | ||
484 | if (val != lpm_priv->shadow.pm_start_stop) | ||
485 | result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id, | ||
486 | val, | ||
487 | PS3_WRITE_PM_MASK, | ||
488 | &dummy); | ||
489 | lpm_priv->shadow.pm_start_stop = val; | ||
490 | break; | ||
491 | case trace_address: | ||
492 | case ext_tr_timer: | ||
493 | case pm_status: | ||
494 | break; | ||
495 | default: | ||
496 | dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__, | ||
497 | __LINE__, reg); | ||
498 | BUG(); | ||
499 | break; | ||
500 | } | ||
501 | |||
502 | if (result) | ||
503 | dev_err(sbd_core(), "%s:%u: lv1 set_control failed: " | ||
504 | "reg %u, %s\n", __func__, __LINE__, reg, | ||
505 | ps3_result(result)); | ||
506 | } | ||
507 | EXPORT_SYMBOL_GPL(ps3_write_pm); | ||
508 | |||
509 | /** | ||
510 | * ps3_get_ctr_size - Get the size of a physical counter. | ||
511 | * | ||
512 | * Returns either 16 or 32. | ||
513 | */ | ||
514 | |||
515 | u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr) | ||
516 | { | ||
517 | u32 pm_ctrl; | ||
518 | |||
519 | if (phys_ctr >= NR_PHYS_CTRS) { | ||
520 | dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, | ||
521 | __LINE__, phys_ctr); | ||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | pm_ctrl = ps3_read_pm(cpu, pm_control); | ||
526 | return (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32; | ||
527 | } | ||
528 | EXPORT_SYMBOL_GPL(ps3_get_ctr_size); | ||
529 | |||
530 | /** | ||
531 | * ps3_set_ctr_size - Set the size of a physical counter to 16 or 32 bits. | ||
532 | */ | ||
533 | |||
534 | void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size) | ||
535 | { | ||
536 | u32 pm_ctrl; | ||
537 | |||
538 | if (phys_ctr >= NR_PHYS_CTRS) { | ||
539 | dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, | ||
540 | __LINE__, phys_ctr); | ||
541 | return; | ||
542 | } | ||
543 | |||
544 | pm_ctrl = ps3_read_pm(cpu, pm_control); | ||
545 | |||
546 | switch (ctr_size) { | ||
547 | case 16: | ||
548 | pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr); | ||
549 | ps3_write_pm(cpu, pm_control, pm_ctrl); | ||
550 | break; | ||
551 | |||
552 | case 32: | ||
553 | pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr); | ||
554 | ps3_write_pm(cpu, pm_control, pm_ctrl); | ||
555 | break; | ||
556 | default: | ||
557 | BUG(); | ||
558 | } | ||
559 | } | ||
560 | EXPORT_SYMBOL_GPL(ps3_set_ctr_size); | ||
561 | |||
562 | static u64 pm_translate_signal_group_number_on_island2(u64 subgroup) | ||
563 | { | ||
564 | |||
565 | if (subgroup == 2) | ||
566 | subgroup = 3; | ||
567 | |||
568 | if (subgroup <= 6) | ||
569 | return PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER + subgroup; | ||
570 | else if (subgroup == 7) | ||
571 | return PM_ISLAND2_SIGNAL_GROUP_NUMBER1; | ||
572 | else | ||
573 | return PM_ISLAND2_SIGNAL_GROUP_NUMBER2; | ||
574 | } | ||
575 | |||
576 | static u64 pm_translate_signal_group_number_on_island3(u64 subgroup) | ||
577 | { | ||
578 | |||
579 | switch (subgroup) { | ||
580 | case 2: | ||
581 | case 3: | ||
582 | case 4: | ||
583 | subgroup += 2; | ||
584 | break; | ||
585 | case 5: | ||
586 | subgroup = 8; | ||
587 | break; | ||
588 | default: | ||
589 | break; | ||
590 | } | ||
591 | return PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER + subgroup; | ||
592 | } | ||
593 | |||
594 | static u64 pm_translate_signal_group_number_on_island4(u64 subgroup) | ||
595 | { | ||
596 | return PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER + subgroup; | ||
597 | } | ||
598 | |||
599 | static u64 pm_translate_signal_group_number_on_island5(u64 subgroup) | ||
600 | { | ||
601 | |||
602 | switch (subgroup) { | ||
603 | case 3: | ||
604 | subgroup = 4; | ||
605 | break; | ||
606 | case 4: | ||
607 | subgroup = 6; | ||
608 | break; | ||
609 | default: | ||
610 | break; | ||
611 | } | ||
612 | return PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER + subgroup; | ||
613 | } | ||
614 | |||
615 | static u64 pm_translate_signal_group_number_on_island6(u64 subgroup, | ||
616 | u64 subsubgroup) | ||
617 | { | ||
618 | switch (subgroup) { | ||
619 | case 3: | ||
620 | case 4: | ||
621 | case 5: | ||
622 | subgroup += 1; | ||
623 | break; | ||
624 | default: | ||
625 | break; | ||
626 | } | ||
627 | |||
628 | switch (subsubgroup) { | ||
629 | case 4: | ||
630 | case 5: | ||
631 | case 6: | ||
632 | subsubgroup += 2; | ||
633 | break; | ||
634 | case 7: | ||
635 | case 8: | ||
636 | case 9: | ||
637 | case 10: | ||
638 | subsubgroup += 4; | ||
639 | break; | ||
640 | case 11: | ||
641 | case 12: | ||
642 | case 13: | ||
643 | subsubgroup += 5; | ||
644 | break; | ||
645 | default: | ||
646 | break; | ||
647 | } | ||
648 | |||
649 | if (subgroup <= 5) | ||
650 | return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup); | ||
651 | else | ||
652 | return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup | ||
653 | + subsubgroup - 1); | ||
654 | } | ||
655 | |||
656 | static u64 pm_translate_signal_group_number_on_island7(u64 subgroup) | ||
657 | { | ||
658 | return PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER + subgroup; | ||
659 | } | ||
660 | |||
661 | static u64 pm_translate_signal_group_number_on_island8(u64 subgroup) | ||
662 | { | ||
663 | return PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER + subgroup; | ||
664 | } | ||
665 | |||
666 | static u64 pm_signal_group_to_ps3_lv1_signal_group(u64 group) | ||
667 | { | ||
668 | u64 island; | ||
669 | u64 subgroup; | ||
670 | u64 subsubgroup; | ||
671 | |||
672 | subgroup = 0; | ||
673 | subsubgroup = 0; | ||
674 | island = 0; | ||
675 | if (group < 1000) { | ||
676 | if (group < 100) { | ||
677 | if (20 <= group && group < 30) { | ||
678 | island = 2; | ||
679 | subgroup = group - 20; | ||
680 | } else if (30 <= group && group < 40) { | ||
681 | island = 3; | ||
682 | subgroup = group - 30; | ||
683 | } else if (40 <= group && group < 50) { | ||
684 | island = 4; | ||
685 | subgroup = group - 40; | ||
686 | } else if (50 <= group && group < 60) { | ||
687 | island = 5; | ||
688 | subgroup = group - 50; | ||
689 | } else if (60 <= group && group < 70) { | ||
690 | island = 6; | ||
691 | subgroup = group - 60; | ||
692 | } else if (70 <= group && group < 80) { | ||
693 | island = 7; | ||
694 | subgroup = group - 70; | ||
695 | } else if (80 <= group && group < 90) { | ||
696 | island = 8; | ||
697 | subgroup = group - 80; | ||
698 | } | ||
699 | } else if (200 <= group && group < 300) { | ||
700 | island = 2; | ||
701 | subgroup = group - 200; | ||
702 | } else if (600 <= group && group < 700) { | ||
703 | island = 6; | ||
704 | subgroup = 5; | ||
705 | subsubgroup = group - 650; | ||
706 | } | ||
707 | } else if (6000 <= group && group < 7000) { | ||
708 | island = 6; | ||
709 | subgroup = 5; | ||
710 | subsubgroup = group - 6500; | ||
711 | } | ||
712 | |||
713 | switch (island) { | ||
714 | case 2: | ||
715 | return pm_translate_signal_group_number_on_island2(subgroup); | ||
716 | case 3: | ||
717 | return pm_translate_signal_group_number_on_island3(subgroup); | ||
718 | case 4: | ||
719 | return pm_translate_signal_group_number_on_island4(subgroup); | ||
720 | case 5: | ||
721 | return pm_translate_signal_group_number_on_island5(subgroup); | ||
722 | case 6: | ||
723 | return pm_translate_signal_group_number_on_island6(subgroup, | ||
724 | subsubgroup); | ||
725 | case 7: | ||
726 | return pm_translate_signal_group_number_on_island7(subgroup); | ||
727 | case 8: | ||
728 | return pm_translate_signal_group_number_on_island8(subgroup); | ||
729 | default: | ||
730 | dev_dbg(sbd_core(), "%s:%u: island not found: %lu\n", __func__, | ||
731 | __LINE__, group); | ||
732 | BUG(); | ||
733 | break; | ||
734 | } | ||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | static u64 pm_bus_word_to_ps3_lv1_bus_word(u8 word) | ||
739 | { | ||
740 | |||
741 | switch (word) { | ||
742 | case 1: | ||
743 | return 0xF000; | ||
744 | case 2: | ||
745 | return 0x0F00; | ||
746 | case 4: | ||
747 | return 0x00F0; | ||
748 | case 8: | ||
749 | default: | ||
750 | return 0x000F; | ||
751 | } | ||
752 | } | ||
753 | |||
754 | static int __ps3_set_signal(u64 lv1_signal_group, u64 bus_select, | ||
755 | u64 signal_select, u64 attr1, u64 attr2, u64 attr3) | ||
756 | { | ||
757 | int ret; | ||
758 | |||
759 | ret = lv1_set_lpm_signal(lpm_priv->lpm_id, lv1_signal_group, bus_select, | ||
760 | signal_select, attr1, attr2, attr3); | ||
761 | if (ret) | ||
762 | dev_err(sbd_core(), | ||
763 | "%s:%u: error:%d 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", | ||
764 | __func__, __LINE__, ret, lv1_signal_group, bus_select, | ||
765 | signal_select, attr1, attr2, attr3); | ||
766 | |||
767 | return ret; | ||
768 | } | ||
769 | |||
770 | int ps3_set_signal(u64 signal_group, u8 signal_bit, u16 sub_unit, | ||
771 | u8 bus_word) | ||
772 | { | ||
773 | int ret; | ||
774 | u64 lv1_signal_group; | ||
775 | u64 bus_select; | ||
776 | u64 signal_select; | ||
777 | u64 attr1, attr2, attr3; | ||
778 | |||
779 | if (signal_group == 0) | ||
780 | return __ps3_set_signal(0, 0, 0, 0, 0, 0); | ||
781 | |||
782 | lv1_signal_group = | ||
783 | pm_signal_group_to_ps3_lv1_signal_group(signal_group); | ||
784 | bus_select = pm_bus_word_to_ps3_lv1_bus_word(bus_word); | ||
785 | |||
786 | switch (signal_group) { | ||
787 | case PM_SIG_GROUP_SPU_TRIGGER: | ||
788 | signal_select = 1; | ||
789 | signal_select = signal_select << (63 - signal_bit); | ||
790 | break; | ||
791 | case PM_SIG_GROUP_SPU_EVENT: | ||
792 | signal_select = 1; | ||
793 | signal_select = (signal_select << (63 - signal_bit)) | 0x3; | ||
794 | break; | ||
795 | default: | ||
796 | signal_select = 0; | ||
797 | break; | ||
798 | } | ||
799 | |||
800 | /* | ||
801 | * 0: physical object. | ||
802 | * 1: logical object. | ||
803 | * This parameter is only used for the PPE and SPE signals. | ||
804 | */ | ||
805 | attr1 = 1; | ||
806 | |||
807 | /* | ||
808 | * This parameter is used to specify the target physical/logical | ||
809 | * PPE/SPE object. | ||
810 | */ | ||
811 | if (PM_SIG_GROUP_SPU <= signal_group && | ||
812 | signal_group < PM_SIG_GROUP_MFC_MAX) | ||
813 | attr2 = sub_unit; | ||
814 | else | ||
815 | attr2 = lpm_priv->pu_id; | ||
816 | |||
817 | /* | ||
818 | * This parameter is only used for setting the SPE signal. | ||
819 | */ | ||
820 | attr3 = 0; | ||
821 | |||
822 | ret = __ps3_set_signal(lv1_signal_group, bus_select, signal_select, | ||
823 | attr1, attr2, attr3); | ||
824 | if (ret) | ||
825 | dev_err(sbd_core(), "%s:%u: __ps3_set_signal failed: %d\n", | ||
826 | __func__, __LINE__, ret); | ||
827 | |||
828 | return ret; | ||
829 | } | ||
830 | EXPORT_SYMBOL_GPL(ps3_set_signal); | ||
831 | |||
832 | u32 ps3_get_hw_thread_id(int cpu) | ||
833 | { | ||
834 | return get_hard_smp_processor_id(cpu); | ||
835 | } | ||
836 | EXPORT_SYMBOL_GPL(ps3_get_hw_thread_id); | ||
837 | |||
838 | /** | ||
839 | * ps3_enable_pm - Enable the entire performance monitoring unit. | ||
840 | * | ||
841 | * When we enable the LPM, all pending writes to counters get committed. | ||
842 | */ | ||
843 | |||
844 | void ps3_enable_pm(u32 cpu) | ||
845 | { | ||
846 | int result; | ||
847 | u64 tmp; | ||
848 | int insert_bookmark = 0; | ||
849 | |||
850 | lpm_priv->tb_count = 0; | ||
851 | |||
852 | if (use_start_stop_bookmark) { | ||
853 | if (!(lpm_priv->shadow.pm_start_stop & | ||
854 | (PS3_PM_START_STOP_START_MASK | ||
855 | | PS3_PM_START_STOP_STOP_MASK))) { | ||
856 | result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id, | ||
857 | (PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START | | ||
858 | PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START | | ||
859 | PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP | | ||
860 | PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP), | ||
861 | 0xFFFFFFFFFFFFFFFFULL, &tmp); | ||
862 | |||
863 | if (result) | ||
864 | dev_err(sbd_core(), "%s:%u: " | ||
865 | "lv1_set_lpm_trigger_control failed: " | ||
866 | "%s\n", __func__, __LINE__, | ||
867 | ps3_result(result)); | ||
868 | |||
869 | insert_bookmark = !result; | ||
870 | } | ||
871 | } | ||
872 | |||
873 | result = lv1_start_lpm(lpm_priv->lpm_id); | ||
874 | |||
875 | if (result) | ||
876 | dev_err(sbd_core(), "%s:%u: lv1_start_lpm failed: %s\n", | ||
877 | __func__, __LINE__, ps3_result(result)); | ||
878 | |||
879 | if (use_start_stop_bookmark && !result && insert_bookmark) | ||
880 | ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_START); | ||
881 | } | ||
882 | EXPORT_SYMBOL_GPL(ps3_enable_pm); | ||
883 | |||
884 | /** | ||
885 | * ps3_disable_pm - Disable the entire performance monitoring unit. | ||
886 | */ | ||
887 | |||
888 | void ps3_disable_pm(u32 cpu) | ||
889 | { | ||
890 | int result; | ||
891 | u64 tmp; | ||
892 | |||
893 | ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_STOP); | ||
894 | |||
895 | result = lv1_stop_lpm(lpm_priv->lpm_id, &tmp); | ||
896 | |||
897 | if (result) { | ||
898 | if(result != LV1_WRONG_STATE) | ||
899 | dev_err(sbd_core(), "%s:%u: lv1_stop_lpm failed: %s\n", | ||
900 | __func__, __LINE__, ps3_result(result)); | ||
901 | return; | ||
902 | } | ||
903 | |||
904 | lpm_priv->tb_count = tmp; | ||
905 | |||
906 | dev_dbg(sbd_core(), "%s:%u: tb_count %lu (%lxh)\n", __func__, __LINE__, | ||
907 | lpm_priv->tb_count, lpm_priv->tb_count); | ||
908 | } | ||
909 | EXPORT_SYMBOL_GPL(ps3_disable_pm); | ||
910 | |||
911 | /** | ||
912 | * ps3_lpm_copy_tb - Copy data from the trace buffer to a kernel buffer. | ||
913 | * @offset: Offset in bytes from the start of the trace buffer. | ||
914 | * @buf: Copy destination. | ||
915 | * @count: Maximum count of bytes to copy. | ||
916 | * @bytes_copied: Pointer to a variable that will recieve the number of | ||
917 | * bytes copied to @buf. | ||
918 | * | ||
919 | * On error @buf will contain any successfully copied trace buffer data | ||
920 | * and bytes_copied will be set to the number of bytes successfully copied. | ||
921 | */ | ||
922 | |||
923 | int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count, | ||
924 | unsigned long *bytes_copied) | ||
925 | { | ||
926 | int result; | ||
927 | |||
928 | *bytes_copied = 0; | ||
929 | |||
930 | if (!lpm_priv->tb_cache) | ||
931 | return -EPERM; | ||
932 | |||
933 | if (offset >= lpm_priv->tb_count) | ||
934 | return 0; | ||
935 | |||
936 | count = min(count, lpm_priv->tb_count - offset); | ||
937 | |||
938 | while (*bytes_copied < count) { | ||
939 | const unsigned long request = count - *bytes_copied; | ||
940 | u64 tmp; | ||
941 | |||
942 | result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset, | ||
943 | request, &tmp); | ||
944 | if (result) { | ||
945 | dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n", | ||
946 | __func__, __LINE__, request, offset); | ||
947 | |||
948 | dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer " | ||
949 | "failed: %s\n", __func__, __LINE__, | ||
950 | ps3_result(result)); | ||
951 | return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL; | ||
952 | } | ||
953 | |||
954 | memcpy(buf, lpm_priv->tb_cache, tmp); | ||
955 | buf += tmp; | ||
956 | *bytes_copied += tmp; | ||
957 | offset += tmp; | ||
958 | } | ||
959 | dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__, | ||
960 | *bytes_copied); | ||
961 | |||
962 | return 0; | ||
963 | } | ||
964 | EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb); | ||
965 | |||
966 | /** | ||
967 | * ps3_lpm_copy_tb_to_user - Copy data from the trace buffer to a user buffer. | ||
968 | * @offset: Offset in bytes from the start of the trace buffer. | ||
969 | * @buf: A __user copy destination. | ||
970 | * @count: Maximum count of bytes to copy. | ||
971 | * @bytes_copied: Pointer to a variable that will recieve the number of | ||
972 | * bytes copied to @buf. | ||
973 | * | ||
974 | * On error @buf will contain any successfully copied trace buffer data | ||
975 | * and bytes_copied will be set to the number of bytes successfully copied. | ||
976 | */ | ||
977 | |||
978 | int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf, | ||
979 | unsigned long count, unsigned long *bytes_copied) | ||
980 | { | ||
981 | int result; | ||
982 | |||
983 | *bytes_copied = 0; | ||
984 | |||
985 | if (!lpm_priv->tb_cache) | ||
986 | return -EPERM; | ||
987 | |||
988 | if (offset >= lpm_priv->tb_count) | ||
989 | return 0; | ||
990 | |||
991 | count = min(count, lpm_priv->tb_count - offset); | ||
992 | |||
993 | while (*bytes_copied < count) { | ||
994 | const unsigned long request = count - *bytes_copied; | ||
995 | u64 tmp; | ||
996 | |||
997 | result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset, | ||
998 | request, &tmp); | ||
999 | if (result) { | ||
1000 | dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n", | ||
1001 | __func__, __LINE__, request, offset); | ||
1002 | dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer " | ||
1003 | "failed: %s\n", __func__, __LINE__, | ||
1004 | ps3_result(result)); | ||
1005 | return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL; | ||
1006 | } | ||
1007 | |||
1008 | result = copy_to_user(buf, lpm_priv->tb_cache, tmp); | ||
1009 | |||
1010 | if (result) { | ||
1011 | dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%p\n", | ||
1012 | __func__, __LINE__, tmp, buf); | ||
1013 | dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n", | ||
1014 | __func__, __LINE__, result); | ||
1015 | return -EFAULT; | ||
1016 | } | ||
1017 | |||
1018 | buf += tmp; | ||
1019 | *bytes_copied += tmp; | ||
1020 | offset += tmp; | ||
1021 | } | ||
1022 | dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__, | ||
1023 | *bytes_copied); | ||
1024 | |||
1025 | return 0; | ||
1026 | } | ||
1027 | EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb_to_user); | ||
1028 | |||
1029 | /** | ||
1030 | * ps3_get_and_clear_pm_interrupts - | ||
1031 | * | ||
1032 | * Clearing interrupts for the entire performance monitoring unit. | ||
1033 | * Reading pm_status clears the interrupt bits. | ||
1034 | */ | ||
1035 | |||
1036 | u32 ps3_get_and_clear_pm_interrupts(u32 cpu) | ||
1037 | { | ||
1038 | return ps3_read_pm(cpu, pm_status); | ||
1039 | } | ||
1040 | EXPORT_SYMBOL_GPL(ps3_get_and_clear_pm_interrupts); | ||
1041 | |||
1042 | /** | ||
1043 | * ps3_enable_pm_interrupts - | ||
1044 | * | ||
1045 | * Enabling interrupts for the entire performance monitoring unit. | ||
1046 | * Enables the interrupt bits in the pm_status register. | ||
1047 | */ | ||
1048 | |||
1049 | void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask) | ||
1050 | { | ||
1051 | if (mask) | ||
1052 | ps3_write_pm(cpu, pm_status, mask); | ||
1053 | } | ||
1054 | EXPORT_SYMBOL_GPL(ps3_enable_pm_interrupts); | ||
1055 | |||
1056 | /** | ||
1057 | * ps3_enable_pm_interrupts - | ||
1058 | * | ||
1059 | * Disabling interrupts for the entire performance monitoring unit. | ||
1060 | */ | ||
1061 | |||
1062 | void ps3_disable_pm_interrupts(u32 cpu) | ||
1063 | { | ||
1064 | ps3_get_and_clear_pm_interrupts(cpu); | ||
1065 | ps3_write_pm(cpu, pm_status, 0); | ||
1066 | } | ||
1067 | EXPORT_SYMBOL_GPL(ps3_disable_pm_interrupts); | ||
1068 | |||
1069 | /** | ||
1070 | * ps3_lpm_open - Open the logical performance monitor device. | ||
1071 | * @tb_type: Specifies the type of trace buffer lv1 sould use for this lpm | ||
1072 | * instance, specified by one of enum ps3_lpm_tb_type. | ||
1073 | * @tb_cache: Optional user supplied buffer to use as the trace buffer cache. | ||
1074 | * If NULL, the driver will allocate and manage an internal buffer. | ||
1075 | * Unused when when @tb_type is PS3_LPM_TB_TYPE_NONE. | ||
1076 | * @tb_cache_size: The size in bytes of the user supplied @tb_cache buffer. | ||
1077 | * Unused when @tb_cache is NULL or @tb_type is PS3_LPM_TB_TYPE_NONE. | ||
1078 | */ | ||
1079 | |||
1080 | int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache, | ||
1081 | u64 tb_cache_size) | ||
1082 | { | ||
1083 | int result; | ||
1084 | u64 tb_size; | ||
1085 | |||
1086 | BUG_ON(!lpm_priv); | ||
1087 | BUG_ON(tb_type != PS3_LPM_TB_TYPE_NONE | ||
1088 | && tb_type != PS3_LPM_TB_TYPE_INTERNAL); | ||
1089 | |||
1090 | if (tb_type == PS3_LPM_TB_TYPE_NONE && tb_cache) | ||
1091 | dev_dbg(sbd_core(), "%s:%u: bad in vals\n", __func__, __LINE__); | ||
1092 | |||
1093 | if (!atomic_add_unless(&lpm_priv->open, 1, 1)) { | ||
1094 | dev_dbg(sbd_core(), "%s:%u: busy\n", __func__, __LINE__); | ||
1095 | return -EBUSY; | ||
1096 | } | ||
1097 | |||
1098 | /* Note tb_cache needs 128 byte alignment. */ | ||
1099 | |||
1100 | if (tb_type == PS3_LPM_TB_TYPE_NONE) { | ||
1101 | lpm_priv->tb_cache_size = 0; | ||
1102 | lpm_priv->tb_cache_internal = NULL; | ||
1103 | lpm_priv->tb_cache = NULL; | ||
1104 | } else if (tb_cache) { | ||
1105 | if (tb_cache != (void *)_ALIGN_UP((unsigned long)tb_cache, 128) | ||
1106 | || tb_cache_size != _ALIGN_UP(tb_cache_size, 128)) { | ||
1107 | dev_err(sbd_core(), "%s:%u: unaligned tb_cache\n", | ||
1108 | __func__, __LINE__); | ||
1109 | result = -EINVAL; | ||
1110 | goto fail_align; | ||
1111 | } | ||
1112 | lpm_priv->tb_cache_size = tb_cache_size; | ||
1113 | lpm_priv->tb_cache_internal = NULL; | ||
1114 | lpm_priv->tb_cache = tb_cache; | ||
1115 | } else { | ||
1116 | lpm_priv->tb_cache_size = PS3_LPM_DEFAULT_TB_CACHE_SIZE; | ||
1117 | lpm_priv->tb_cache_internal = kzalloc( | ||
1118 | lpm_priv->tb_cache_size + 127, GFP_KERNEL); | ||
1119 | if (!lpm_priv->tb_cache_internal) { | ||
1120 | dev_err(sbd_core(), "%s:%u: alloc internal tb_cache " | ||
1121 | "failed\n", __func__, __LINE__); | ||
1122 | result = -ENOMEM; | ||
1123 | goto fail_malloc; | ||
1124 | } | ||
1125 | lpm_priv->tb_cache = (void *)_ALIGN_UP( | ||
1126 | (unsigned long)lpm_priv->tb_cache_internal, 128); | ||
1127 | } | ||
1128 | |||
1129 | result = lv1_construct_lpm(lpm_priv->node_id, tb_type, 0, 0, | ||
1130 | ps3_mm_phys_to_lpar(__pa(lpm_priv->tb_cache)), | ||
1131 | lpm_priv->tb_cache_size, &lpm_priv->lpm_id, | ||
1132 | &lpm_priv->outlet_id, &tb_size); | ||
1133 | |||
1134 | if (result) { | ||
1135 | dev_err(sbd_core(), "%s:%u: lv1_construct_lpm failed: %s\n", | ||
1136 | __func__, __LINE__, ps3_result(result)); | ||
1137 | result = -EINVAL; | ||
1138 | goto fail_construct; | ||
1139 | } | ||
1140 | |||
1141 | lpm_priv->shadow.pm_control = PS3_LPM_SHADOW_REG_INIT; | ||
1142 | lpm_priv->shadow.pm_start_stop = PS3_LPM_SHADOW_REG_INIT; | ||
1143 | lpm_priv->shadow.pm_interval = PS3_LPM_SHADOW_REG_INIT; | ||
1144 | lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT; | ||
1145 | lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT; | ||
1146 | |||
1147 | dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%lx, outlet_id 0x%lx, " | ||
1148 | "tb_size 0x%lx\n", __func__, __LINE__, lpm_priv->lpm_id, | ||
1149 | lpm_priv->outlet_id, tb_size); | ||
1150 | |||
1151 | return 0; | ||
1152 | |||
1153 | fail_construct: | ||
1154 | kfree(lpm_priv->tb_cache_internal); | ||
1155 | lpm_priv->tb_cache_internal = NULL; | ||
1156 | fail_malloc: | ||
1157 | fail_align: | ||
1158 | atomic_dec(&lpm_priv->open); | ||
1159 | return result; | ||
1160 | } | ||
1161 | EXPORT_SYMBOL_GPL(ps3_lpm_open); | ||
1162 | |||
1163 | /** | ||
1164 | * ps3_lpm_close - Close the lpm device. | ||
1165 | * | ||
1166 | */ | ||
1167 | |||
1168 | int ps3_lpm_close(void) | ||
1169 | { | ||
1170 | dev_dbg(sbd_core(), "%s:%u\n", __func__, __LINE__); | ||
1171 | |||
1172 | lv1_destruct_lpm(lpm_priv->lpm_id); | ||
1173 | lpm_priv->lpm_id = 0; | ||
1174 | |||
1175 | kfree(lpm_priv->tb_cache_internal); | ||
1176 | lpm_priv->tb_cache_internal = NULL; | ||
1177 | |||
1178 | atomic_dec(&lpm_priv->open); | ||
1179 | return 0; | ||
1180 | } | ||
1181 | EXPORT_SYMBOL_GPL(ps3_lpm_close); | ||
1182 | |||
1183 | static int __devinit ps3_lpm_probe(struct ps3_system_bus_device *dev) | ||
1184 | { | ||
1185 | dev_dbg(&dev->core, " -> %s:%u\n", __func__, __LINE__); | ||
1186 | |||
1187 | if (lpm_priv) { | ||
1188 | dev_info(&dev->core, "%s:%u: called twice\n", | ||
1189 | __func__, __LINE__); | ||
1190 | return -EBUSY; | ||
1191 | } | ||
1192 | |||
1193 | lpm_priv = kzalloc(sizeof(*lpm_priv), GFP_KERNEL); | ||
1194 | |||
1195 | if (!lpm_priv) | ||
1196 | return -ENOMEM; | ||
1197 | |||
1198 | lpm_priv->sbd = dev; | ||
1199 | lpm_priv->node_id = dev->lpm.node_id; | ||
1200 | lpm_priv->pu_id = dev->lpm.pu_id; | ||
1201 | lpm_priv->rights = dev->lpm.rights; | ||
1202 | |||
1203 | dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__); | ||
1204 | |||
1205 | return 0; | ||
1206 | } | ||
1207 | |||
1208 | static int ps3_lpm_remove(struct ps3_system_bus_device *dev) | ||
1209 | { | ||
1210 | dev_dbg(&dev->core, " -> %s:%u:\n", __func__, __LINE__); | ||
1211 | |||
1212 | ps3_lpm_close(); | ||
1213 | |||
1214 | kfree(lpm_priv); | ||
1215 | lpm_priv = NULL; | ||
1216 | |||
1217 | dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__); | ||
1218 | return 0; | ||
1219 | } | ||
1220 | |||
1221 | static struct ps3_system_bus_driver ps3_lpm_driver = { | ||
1222 | .match_id = PS3_MATCH_ID_LPM, | ||
1223 | .core.name = "ps3-lpm", | ||
1224 | .core.owner = THIS_MODULE, | ||
1225 | .probe = ps3_lpm_probe, | ||
1226 | .remove = ps3_lpm_remove, | ||
1227 | .shutdown = ps3_lpm_remove, | ||
1228 | }; | ||
1229 | |||
1230 | static int __init ps3_lpm_init(void) | ||
1231 | { | ||
1232 | pr_debug("%s:%d:\n", __func__, __LINE__); | ||
1233 | return ps3_system_bus_driver_register(&ps3_lpm_driver); | ||
1234 | } | ||
1235 | |||
1236 | static void __exit ps3_lpm_exit(void) | ||
1237 | { | ||
1238 | pr_debug("%s:%d:\n", __func__, __LINE__); | ||
1239 | ps3_system_bus_driver_unregister(&ps3_lpm_driver); | ||
1240 | } | ||
1241 | |||
1242 | module_init(ps3_lpm_init); | ||
1243 | module_exit(ps3_lpm_exit); | ||
1244 | |||
1245 | MODULE_LICENSE("GPL v2"); | ||
1246 | MODULE_DESCRIPTION("PS3 Logical Performance Monitor Driver"); | ||
1247 | MODULE_AUTHOR("Sony Corporation"); | ||
1248 | MODULE_ALIAS(PS3_MODULE_ALIAS_LPM); | ||
diff --git a/drivers/ps3/ps3-sys-manager.c b/drivers/ps3/ps3-sys-manager.c index 8461b08ab9fb..c3c3aba3ffce 100644 --- a/drivers/ps3/ps3-sys-manager.c +++ b/drivers/ps3/ps3-sys-manager.c | |||
@@ -452,7 +452,7 @@ static int ps3_sys_manager_handle_event(struct ps3_system_bus_device *dev) | |||
452 | case PS3_SM_EVENT_THERMAL_ALERT: | 452 | case PS3_SM_EVENT_THERMAL_ALERT: |
453 | dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n", | 453 | dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n", |
454 | __func__, __LINE__, event.value); | 454 | __func__, __LINE__, event.value); |
455 | printk(KERN_INFO "PS3 Thermal Alert Zone %u\n", event.value); | 455 | pr_info("PS3 Thermal Alert Zone %u\n", event.value); |
456 | break; | 456 | break; |
457 | case PS3_SM_EVENT_THERMAL_CLEARED: | 457 | case PS3_SM_EVENT_THERMAL_CLEARED: |
458 | dev_dbg(&dev->core, "%s:%d: THERMAL_CLEARED (zone %u)\n", | 458 | dev_dbg(&dev->core, "%s:%d: THERMAL_CLEARED (zone %u)\n", |
@@ -488,7 +488,7 @@ static int ps3_sys_manager_handle_cmd(struct ps3_system_bus_device *dev) | |||
488 | result = ps3_vuart_read(dev, &cmd, sizeof(cmd)); | 488 | result = ps3_vuart_read(dev, &cmd, sizeof(cmd)); |
489 | BUG_ON(result && "need to retry here"); | 489 | BUG_ON(result && "need to retry here"); |
490 | 490 | ||
491 | if(result) | 491 | if (result) |
492 | return result; | 492 | return result; |
493 | 493 | ||
494 | if (cmd.version != 1) { | 494 | if (cmd.version != 1) { |
@@ -521,7 +521,7 @@ static int ps3_sys_manager_handle_msg(struct ps3_system_bus_device *dev) | |||
521 | result = ps3_vuart_read(dev, &header, | 521 | result = ps3_vuart_read(dev, &header, |
522 | sizeof(struct ps3_sys_manager_header)); | 522 | sizeof(struct ps3_sys_manager_header)); |
523 | 523 | ||
524 | if(result) | 524 | if (result) |
525 | return result; | 525 | return result; |
526 | 526 | ||
527 | if (header.version != 1) { | 527 | if (header.version != 1) { |
@@ -589,9 +589,9 @@ static void ps3_sys_manager_final_power_off(struct ps3_system_bus_device *dev) | |||
589 | PS3_SM_WAKE_DEFAULT); | 589 | PS3_SM_WAKE_DEFAULT); |
590 | ps3_sys_manager_send_request_shutdown(dev); | 590 | ps3_sys_manager_send_request_shutdown(dev); |
591 | 591 | ||
592 | printk(KERN_EMERG "System Halted, OK to turn off power\n"); | 592 | pr_emerg("System Halted, OK to turn off power\n"); |
593 | 593 | ||
594 | while(1) | 594 | while (1) |
595 | ps3_sys_manager_handle_msg(dev); | 595 | ps3_sys_manager_handle_msg(dev); |
596 | } | 596 | } |
597 | 597 | ||
@@ -626,9 +626,9 @@ static void ps3_sys_manager_final_restart(struct ps3_system_bus_device *dev) | |||
626 | PS3_SM_WAKE_DEFAULT); | 626 | PS3_SM_WAKE_DEFAULT); |
627 | ps3_sys_manager_send_request_shutdown(dev); | 627 | ps3_sys_manager_send_request_shutdown(dev); |
628 | 628 | ||
629 | printk(KERN_EMERG "System Halted, OK to turn off power\n"); | 629 | pr_emerg("System Halted, OK to turn off power\n"); |
630 | 630 | ||
631 | while(1) | 631 | while (1) |
632 | ps3_sys_manager_handle_msg(dev); | 632 | ps3_sys_manager_handle_msg(dev); |
633 | } | 633 | } |
634 | 634 | ||
diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c index bb8d5b1eec90..90c097a7a47a 100644 --- a/drivers/ps3/ps3-vuart.c +++ b/drivers/ps3/ps3-vuart.c | |||
@@ -108,18 +108,18 @@ static struct ps3_vuart_port_priv *to_port_priv( | |||
108 | struct ports_bmp { | 108 | struct ports_bmp { |
109 | u64 status; | 109 | u64 status; |
110 | u64 unused[3]; | 110 | u64 unused[3]; |
111 | } __attribute__ ((aligned (32))); | 111 | } __attribute__((aligned(32))); |
112 | 112 | ||
113 | #define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__) | 113 | #define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__) |
114 | static void __maybe_unused _dump_ports_bmp( | 114 | static void __maybe_unused _dump_ports_bmp( |
115 | const struct ports_bmp* bmp, const char* func, int line) | 115 | const struct ports_bmp *bmp, const char *func, int line) |
116 | { | 116 | { |
117 | pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status); | 117 | pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status); |
118 | } | 118 | } |
119 | 119 | ||
120 | #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__) | 120 | #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__) |
121 | static void __maybe_unused _dump_port_params(unsigned int port_number, | 121 | static void __maybe_unused _dump_port_params(unsigned int port_number, |
122 | const char* func, int line) | 122 | const char *func, int line) |
123 | { | 123 | { |
124 | #if defined(DEBUG) | 124 | #if defined(DEBUG) |
125 | static const char *strings[] = { | 125 | static const char *strings[] = { |
@@ -363,7 +363,7 @@ int ps3_vuart_disable_interrupt_disconnect(struct ps3_system_bus_device *dev) | |||
363 | */ | 363 | */ |
364 | 364 | ||
365 | static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev, | 365 | static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev, |
366 | const void* buf, unsigned int bytes, unsigned long *bytes_written) | 366 | const void *buf, unsigned int bytes, unsigned long *bytes_written) |
367 | { | 367 | { |
368 | int result; | 368 | int result; |
369 | struct ps3_vuart_port_priv *priv = to_port_priv(dev); | 369 | struct ps3_vuart_port_priv *priv = to_port_priv(dev); |
@@ -431,7 +431,7 @@ void ps3_vuart_clear_rx_bytes(struct ps3_system_bus_device *dev, | |||
431 | int result; | 431 | int result; |
432 | struct ps3_vuart_port_priv *priv = to_port_priv(dev); | 432 | struct ps3_vuart_port_priv *priv = to_port_priv(dev); |
433 | u64 bytes_waiting; | 433 | u64 bytes_waiting; |
434 | void* tmp; | 434 | void *tmp; |
435 | 435 | ||
436 | result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes_waiting); | 436 | result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes_waiting); |
437 | 437 | ||
@@ -526,9 +526,8 @@ int ps3_vuart_write(struct ps3_system_bus_device *dev, const void *buf, | |||
526 | 526 | ||
527 | lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL); | 527 | lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL); |
528 | 528 | ||
529 | if (!lb) { | 529 | if (!lb) |
530 | return -ENOMEM; | 530 | return -ENOMEM; |
531 | } | ||
532 | 531 | ||
533 | memcpy(lb->data, buf, bytes); | 532 | memcpy(lb->data, buf, bytes); |
534 | lb->head = lb->data; | 533 | lb->head = lb->data; |
@@ -878,7 +877,7 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_system_bus_device *dev) | |||
878 | struct vuart_bus_priv { | 877 | struct vuart_bus_priv { |
879 | struct ports_bmp *bmp; | 878 | struct ports_bmp *bmp; |
880 | unsigned int virq; | 879 | unsigned int virq; |
881 | struct semaphore probe_mutex; | 880 | struct mutex probe_mutex; |
882 | int use_count; | 881 | int use_count; |
883 | struct ps3_system_bus_device *devices[PORT_COUNT]; | 882 | struct ps3_system_bus_device *devices[PORT_COUNT]; |
884 | } static vuart_bus_priv; | 883 | } static vuart_bus_priv; |
@@ -926,9 +925,8 @@ static int ps3_vuart_bus_interrupt_get(void) | |||
926 | 925 | ||
927 | BUG_ON(vuart_bus_priv.use_count > 2); | 926 | BUG_ON(vuart_bus_priv.use_count > 2); |
928 | 927 | ||
929 | if (vuart_bus_priv.use_count != 1) { | 928 | if (vuart_bus_priv.use_count != 1) |
930 | return 0; | 929 | return 0; |
931 | } | ||
932 | 930 | ||
933 | BUG_ON(vuart_bus_priv.bmp); | 931 | BUG_ON(vuart_bus_priv.bmp); |
934 | 932 | ||
@@ -1017,7 +1015,7 @@ static int ps3_vuart_probe(struct ps3_system_bus_device *dev) | |||
1017 | return -EINVAL; | 1015 | return -EINVAL; |
1018 | } | 1016 | } |
1019 | 1017 | ||
1020 | down(&vuart_bus_priv.probe_mutex); | 1018 | mutex_lock(&vuart_bus_priv.probe_mutex); |
1021 | 1019 | ||
1022 | result = ps3_vuart_bus_interrupt_get(); | 1020 | result = ps3_vuart_bus_interrupt_get(); |
1023 | 1021 | ||
@@ -1077,7 +1075,7 @@ static int ps3_vuart_probe(struct ps3_system_bus_device *dev) | |||
1077 | goto fail_probe; | 1075 | goto fail_probe; |
1078 | } | 1076 | } |
1079 | 1077 | ||
1080 | up(&vuart_bus_priv.probe_mutex); | 1078 | mutex_unlock(&vuart_bus_priv.probe_mutex); |
1081 | 1079 | ||
1082 | return result; | 1080 | return result; |
1083 | 1081 | ||
@@ -1090,7 +1088,7 @@ fail_dev_malloc: | |||
1090 | fail_busy: | 1088 | fail_busy: |
1091 | ps3_vuart_bus_interrupt_put(); | 1089 | ps3_vuart_bus_interrupt_put(); |
1092 | fail_setup_interrupt: | 1090 | fail_setup_interrupt: |
1093 | up(&vuart_bus_priv.probe_mutex); | 1091 | mutex_unlock(&vuart_bus_priv.probe_mutex); |
1094 | dev_dbg(&dev->core, "%s:%d: failed\n", __func__, __LINE__); | 1092 | dev_dbg(&dev->core, "%s:%d: failed\n", __func__, __LINE__); |
1095 | return result; | 1093 | return result; |
1096 | } | 1094 | } |
@@ -1129,7 +1127,7 @@ static int ps3_vuart_remove(struct ps3_system_bus_device *dev) | |||
1129 | 1127 | ||
1130 | BUG_ON(!dev); | 1128 | BUG_ON(!dev); |
1131 | 1129 | ||
1132 | down(&vuart_bus_priv.probe_mutex); | 1130 | mutex_lock(&vuart_bus_priv.probe_mutex); |
1133 | 1131 | ||
1134 | dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, | 1132 | dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, |
1135 | dev->match_id); | 1133 | dev->match_id); |
@@ -1137,7 +1135,7 @@ static int ps3_vuart_remove(struct ps3_system_bus_device *dev) | |||
1137 | if (!dev->core.driver) { | 1135 | if (!dev->core.driver) { |
1138 | dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, | 1136 | dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, |
1139 | __LINE__); | 1137 | __LINE__); |
1140 | up(&vuart_bus_priv.probe_mutex); | 1138 | mutex_unlock(&vuart_bus_priv.probe_mutex); |
1141 | return 0; | 1139 | return 0; |
1142 | } | 1140 | } |
1143 | 1141 | ||
@@ -1160,7 +1158,7 @@ static int ps3_vuart_remove(struct ps3_system_bus_device *dev) | |||
1160 | priv = NULL; | 1158 | priv = NULL; |
1161 | 1159 | ||
1162 | dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); | 1160 | dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); |
1163 | up(&vuart_bus_priv.probe_mutex); | 1161 | mutex_unlock(&vuart_bus_priv.probe_mutex); |
1164 | return 0; | 1162 | return 0; |
1165 | } | 1163 | } |
1166 | 1164 | ||
@@ -1180,7 +1178,7 @@ static int ps3_vuart_shutdown(struct ps3_system_bus_device *dev) | |||
1180 | 1178 | ||
1181 | BUG_ON(!dev); | 1179 | BUG_ON(!dev); |
1182 | 1180 | ||
1183 | down(&vuart_bus_priv.probe_mutex); | 1181 | mutex_lock(&vuart_bus_priv.probe_mutex); |
1184 | 1182 | ||
1185 | dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, | 1183 | dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, |
1186 | dev->match_id); | 1184 | dev->match_id); |
@@ -1188,7 +1186,7 @@ static int ps3_vuart_shutdown(struct ps3_system_bus_device *dev) | |||
1188 | if (!dev->core.driver) { | 1186 | if (!dev->core.driver) { |
1189 | dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, | 1187 | dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, |
1190 | __LINE__); | 1188 | __LINE__); |
1191 | up(&vuart_bus_priv.probe_mutex); | 1189 | mutex_unlock(&vuart_bus_priv.probe_mutex); |
1192 | return 0; | 1190 | return 0; |
1193 | } | 1191 | } |
1194 | 1192 | ||
@@ -1212,7 +1210,7 @@ static int ps3_vuart_shutdown(struct ps3_system_bus_device *dev) | |||
1212 | 1210 | ||
1213 | dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); | 1211 | dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); |
1214 | 1212 | ||
1215 | up(&vuart_bus_priv.probe_mutex); | 1213 | mutex_unlock(&vuart_bus_priv.probe_mutex); |
1216 | return 0; | 1214 | return 0; |
1217 | } | 1215 | } |
1218 | 1216 | ||
@@ -1223,7 +1221,7 @@ static int __init ps3_vuart_bus_init(void) | |||
1223 | if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) | 1221 | if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) |
1224 | return -ENODEV; | 1222 | return -ENODEV; |
1225 | 1223 | ||
1226 | init_MUTEX(&vuart_bus_priv.probe_mutex); | 1224 | mutex_init(&vuart_bus_priv.probe_mutex); |
1227 | 1225 | ||
1228 | return 0; | 1226 | return 0; |
1229 | } | 1227 | } |
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index f644807da2f9..80c5f1ba2e49 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/interrupt.h> | ||
26 | 27 | ||
27 | #include "rio.h" | 28 | #include "rio.h" |
28 | 29 | ||
@@ -476,8 +477,8 @@ int rio_init_mports(void) | |||
476 | port->iores.end - port->iores.start, | 477 | port->iores.end - port->iores.start, |
477 | port->name)) { | 478 | port->name)) { |
478 | printk(KERN_ERR | 479 | printk(KERN_ERR |
479 | "RIO: Error requesting master port region %8.8lx-%8.8lx\n", | 480 | "RIO: Error requesting master port region 0x%016llx-0x%016llx\n", |
480 | port->iores.start, port->iores.end - 1); | 481 | (u64)port->iores.start, (u64)port->iores.end - 1); |
481 | rc = -ENOMEM; | 482 | rc = -ENOMEM; |
482 | goto out; | 483 | goto out; |
483 | } | 484 | } |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index d7e1996e2fec..d962b74e3114 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -1284,4 +1284,14 @@ config SERIAL_OF_PLATFORM | |||
1284 | Currently, only 8250 compatible ports are supported, but | 1284 | Currently, only 8250 compatible ports are supported, but |
1285 | others can easily be added. | 1285 | others can easily be added. |
1286 | 1286 | ||
1287 | config SERIAL_QE | ||
1288 | tristate "Freescale QUICC Engine serial port support" | ||
1289 | depends on QUICC_ENGINE | ||
1290 | select SERIAL_CORE | ||
1291 | select FW_LOADER | ||
1292 | default n | ||
1293 | help | ||
1294 | This driver supports the QE serial ports on Freescale embedded | ||
1295 | PowerPC that contain a QUICC Engine. | ||
1296 | |||
1287 | endmenu | 1297 | endmenu |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index af6377d480d7..7eb45534778e 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -64,3 +64,4 @@ obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o | |||
64 | obj-$(CONFIG_SERIAL_NETX) += netx-serial.o | 64 | obj-$(CONFIG_SERIAL_NETX) += netx-serial.o |
65 | obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o | 65 | obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o |
66 | obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o | 66 | obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o |
67 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 52fb044bb79a..6ea0366e26ae 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c | |||
@@ -52,11 +52,7 @@ | |||
52 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | 52 | #ifdef CONFIG_PPC_CPM_NEW_BINDING |
53 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | 53 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) |
54 | { | 54 | { |
55 | u16 __iomem *cpcr = &cpmp->cp_cpcr; | 55 | cpm_command(port->command, cmd); |
56 | |||
57 | out_be16(cpcr, port->command | (cmd << 8) | CPM_CR_FLG); | ||
58 | while (in_be16(cpcr) & CPM_CR_FLG) | ||
59 | ; | ||
60 | } | 56 | } |
61 | #else | 57 | #else |
62 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | 58 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h index 9b5465fb0bbb..ddf46d3c964b 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h | |||
@@ -10,7 +10,7 @@ | |||
10 | #ifndef CPM_UART_CPM1_H | 10 | #ifndef CPM_UART_CPM1_H |
11 | #define CPM_UART_CPM1_H | 11 | #define CPM_UART_CPM1_H |
12 | 12 | ||
13 | #include <asm/commproc.h> | 13 | #include <asm/cpm1.h> |
14 | 14 | ||
15 | /* defines for IRQs */ | 15 | /* defines for IRQs */ |
16 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | 16 | #ifndef CONFIG_PPC_CPM_NEW_BINDING |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 882dbc17d590..d9af06a791ba 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c | |||
@@ -52,13 +52,7 @@ | |||
52 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | 52 | #ifdef CONFIG_PPC_CPM_NEW_BINDING |
53 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | 53 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) |
54 | { | 54 | { |
55 | cpm_cpm2_t __iomem *cp = cpm2_map(im_cpm); | 55 | cpm_command(port->command, cmd); |
56 | |||
57 | out_be32(&cp->cp_cpcr, port->command | cmd | CPM_CR_FLG); | ||
58 | while (in_be32(&cp->cp_cpcr) & CPM_CR_FLG) | ||
59 | ; | ||
60 | |||
61 | cpm2_unmap(cp); | ||
62 | } | 56 | } |
63 | #else | 57 | #else |
64 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) | 58 | void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) |
@@ -171,9 +165,9 @@ void scc2_lineif(struct uart_cpm_port *pinfo) | |||
171 | * really has to get out of the driver so boards can | 165 | * really has to get out of the driver so boards can |
172 | * be supported in a sane fashion. | 166 | * be supported in a sane fashion. |
173 | */ | 167 | */ |
168 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
174 | #ifndef CONFIG_STX_GP3 | 169 | #ifndef CONFIG_STX_GP3 |
175 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); | 170 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); |
176 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
177 | 171 | ||
178 | io->iop_pparb |= 0x008b0000; | 172 | io->iop_pparb |= 0x008b0000; |
179 | io->iop_pdirb |= 0x00880000; | 173 | io->iop_pdirb |= 0x00880000; |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index ec36ad78d2fe..3c4d29e59b2c 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -36,7 +36,7 @@ | |||
36 | * DCD. However, the pin multiplexing aren't changed and should be set either | 36 | * DCD. However, the pin multiplexing aren't changed and should be set either |
37 | * by the bootloader or in the platform init code. | 37 | * by the bootloader or in the platform init code. |
38 | * | 38 | * |
39 | * The idx field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2, | 39 | * The idx field must be equal to the PSC index (e.g. 0 for PSC1, 1 for PSC2, |
40 | * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and | 40 | * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and |
41 | * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly | 41 | * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly |
42 | * fpr the console code : without this 1:1 mapping, at early boot time, when we | 42 | * fpr the console code : without this 1:1 mapping, at early boot time, when we |
@@ -68,11 +68,12 @@ | |||
68 | #include <linux/sysrq.h> | 68 | #include <linux/sysrq.h> |
69 | #include <linux/console.h> | 69 | #include <linux/console.h> |
70 | 70 | ||
71 | #include <asm/delay.h> | 71 | #include <linux/delay.h> |
72 | #include <asm/io.h> | 72 | #include <linux/io.h> |
73 | 73 | ||
74 | #if defined(CONFIG_PPC_MERGE) | 74 | #if defined(CONFIG_PPC_MERGE) |
75 | #include <asm/of_platform.h> | 75 | #include <linux/of.h> |
76 | #include <linux/of_platform.h> | ||
76 | #else | 77 | #else |
77 | #include <linux/platform_device.h> | 78 | #include <linux/platform_device.h> |
78 | #endif | 79 | #endif |
@@ -111,23 +112,27 @@ static void mpc52xx_uart_of_enumerate(void); | |||
111 | #endif | 112 | #endif |
112 | 113 | ||
113 | #define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) | 114 | #define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) |
115 | #define FIFO(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) | ||
114 | 116 | ||
115 | 117 | ||
116 | /* Forward declaration of the interruption handling routine */ | 118 | /* Forward declaration of the interruption handling routine */ |
117 | static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id); | 119 | static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id); |
118 | 120 | ||
119 | 121 | ||
120 | /* Simple macro to test if a port is console or not. This one is taken | 122 | /* Simple macro to test if a port is console or not. This one is taken |
121 | * for serial_core.c and maybe should be moved to serial_core.h ? */ | 123 | * for serial_core.c and maybe should be moved to serial_core.h ? */ |
122 | #ifdef CONFIG_SERIAL_CORE_CONSOLE | 124 | #ifdef CONFIG_SERIAL_CORE_CONSOLE |
123 | #define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line) | 125 | #define uart_console(port) \ |
126 | ((port)->cons && (port)->cons->index == (port)->line) | ||
124 | #else | 127 | #else |
125 | #define uart_console(port) (0) | 128 | #define uart_console(port) (0) |
126 | #endif | 129 | #endif |
127 | 130 | ||
128 | #if defined(CONFIG_PPC_MERGE) | 131 | #if defined(CONFIG_PPC_MERGE) |
129 | static struct of_device_id mpc52xx_uart_of_match[] = { | 132 | static struct of_device_id mpc52xx_uart_of_match[] = { |
130 | { .type = "serial", .compatible = "mpc5200-psc-uart", }, | 133 | { .type = "serial", .compatible = "fsl,mpc5200-psc-uart", }, |
134 | { .type = "serial", .compatible = "mpc5200-psc-uart", }, /* lite5200 */ | ||
135 | { .type = "serial", .compatible = "mpc5200-serial", }, /* efika */ | ||
131 | {}, | 136 | {}, |
132 | }; | 137 | }; |
133 | #endif | 138 | #endif |
@@ -162,7 +167,7 @@ mpc52xx_uart_stop_tx(struct uart_port *port) | |||
162 | { | 167 | { |
163 | /* port->lock taken by caller */ | 168 | /* port->lock taken by caller */ |
164 | port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; | 169 | port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; |
165 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 170 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
166 | } | 171 | } |
167 | 172 | ||
168 | static void | 173 | static void |
@@ -170,7 +175,7 @@ mpc52xx_uart_start_tx(struct uart_port *port) | |||
170 | { | 175 | { |
171 | /* port->lock taken by caller */ | 176 | /* port->lock taken by caller */ |
172 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; | 177 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; |
173 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 178 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
174 | } | 179 | } |
175 | 180 | ||
176 | static void | 181 | static void |
@@ -184,7 +189,7 @@ mpc52xx_uart_send_xchar(struct uart_port *port, char ch) | |||
184 | /* Make sure tx interrupts are on */ | 189 | /* Make sure tx interrupts are on */ |
185 | /* Truly necessary ??? They should be anyway */ | 190 | /* Truly necessary ??? They should be anyway */ |
186 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; | 191 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; |
187 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 192 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
188 | } | 193 | } |
189 | 194 | ||
190 | spin_unlock_irqrestore(&port->lock, flags); | 195 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -195,7 +200,7 @@ mpc52xx_uart_stop_rx(struct uart_port *port) | |||
195 | { | 200 | { |
196 | /* port->lock taken by caller */ | 201 | /* port->lock taken by caller */ |
197 | port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY; | 202 | port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY; |
198 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 203 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
199 | } | 204 | } |
200 | 205 | ||
201 | static void | 206 | static void |
@@ -210,10 +215,10 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl) | |||
210 | unsigned long flags; | 215 | unsigned long flags; |
211 | spin_lock_irqsave(&port->lock, flags); | 216 | spin_lock_irqsave(&port->lock, flags); |
212 | 217 | ||
213 | if ( ctl == -1 ) | 218 | if (ctl == -1) |
214 | out_8(&PSC(port)->command,MPC52xx_PSC_START_BRK); | 219 | out_8(&PSC(port)->command, MPC52xx_PSC_START_BRK); |
215 | else | 220 | else |
216 | out_8(&PSC(port)->command,MPC52xx_PSC_STOP_BRK); | 221 | out_8(&PSC(port)->command, MPC52xx_PSC_STOP_BRK); |
217 | 222 | ||
218 | spin_unlock_irqrestore(&port->lock, flags); | 223 | spin_unlock_irqrestore(&port->lock, flags); |
219 | } | 224 | } |
@@ -222,6 +227,7 @@ static int | |||
222 | mpc52xx_uart_startup(struct uart_port *port) | 227 | mpc52xx_uart_startup(struct uart_port *port) |
223 | { | 228 | { |
224 | struct mpc52xx_psc __iomem *psc = PSC(port); | 229 | struct mpc52xx_psc __iomem *psc = PSC(port); |
230 | struct mpc52xx_psc_fifo __iomem *fifo = FIFO(port); | ||
225 | int ret; | 231 | int ret; |
226 | 232 | ||
227 | /* Request IRQ */ | 233 | /* Request IRQ */ |
@@ -231,23 +237,23 @@ mpc52xx_uart_startup(struct uart_port *port) | |||
231 | return ret; | 237 | return ret; |
232 | 238 | ||
233 | /* Reset/activate the port, clear and enable interrupts */ | 239 | /* Reset/activate the port, clear and enable interrupts */ |
234 | out_8(&psc->command,MPC52xx_PSC_RST_RX); | 240 | out_8(&psc->command, MPC52xx_PSC_RST_RX); |
235 | out_8(&psc->command,MPC52xx_PSC_RST_TX); | 241 | out_8(&psc->command, MPC52xx_PSC_RST_TX); |
236 | 242 | ||
237 | out_be32(&psc->sicr,0); /* UART mode DCD ignored */ | 243 | out_be32(&psc->sicr, 0); /* UART mode DCD ignored */ |
238 | 244 | ||
239 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ | 245 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ |
240 | 246 | ||
241 | out_8(&psc->rfcntl, 0x00); | 247 | out_8(&fifo->rfcntl, 0x00); |
242 | out_be16(&psc->rfalarm, 0x1ff); | 248 | out_be16(&fifo->rfalarm, 0x1ff); |
243 | out_8(&psc->tfcntl, 0x07); | 249 | out_8(&fifo->tfcntl, 0x07); |
244 | out_be16(&psc->tfalarm, 0x80); | 250 | out_be16(&fifo->tfalarm, 0x80); |
245 | 251 | ||
246 | port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY; | 252 | port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY; |
247 | out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); | 253 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); |
248 | 254 | ||
249 | out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); | 255 | out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); |
250 | out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); | 256 | out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); |
251 | 257 | ||
252 | return 0; | 258 | return 0; |
253 | } | 259 | } |
@@ -258,12 +264,12 @@ mpc52xx_uart_shutdown(struct uart_port *port) | |||
258 | struct mpc52xx_psc __iomem *psc = PSC(port); | 264 | struct mpc52xx_psc __iomem *psc = PSC(port); |
259 | 265 | ||
260 | /* Shut down the port. Leave TX active if on a console port */ | 266 | /* Shut down the port. Leave TX active if on a console port */ |
261 | out_8(&psc->command,MPC52xx_PSC_RST_RX); | 267 | out_8(&psc->command, MPC52xx_PSC_RST_RX); |
262 | if (!uart_console(port)) | 268 | if (!uart_console(port)) |
263 | out_8(&psc->command,MPC52xx_PSC_RST_TX); | 269 | out_8(&psc->command, MPC52xx_PSC_RST_TX); |
264 | 270 | ||
265 | port->read_status_mask = 0; | 271 | port->read_status_mask = 0; |
266 | out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); | 272 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); |
267 | 273 | ||
268 | /* Release interrupt */ | 274 | /* Release interrupt */ |
269 | free_irq(port->irq, port); | 275 | free_irq(port->irq, port); |
@@ -271,7 +277,7 @@ mpc52xx_uart_shutdown(struct uart_port *port) | |||
271 | 277 | ||
272 | static void | 278 | static void |
273 | mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | 279 | mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, |
274 | struct ktermios *old) | 280 | struct ktermios *old) |
275 | { | 281 | { |
276 | struct mpc52xx_psc __iomem *psc = PSC(port); | 282 | struct mpc52xx_psc __iomem *psc = PSC(port); |
277 | unsigned long flags; | 283 | unsigned long flags; |
@@ -283,14 +289,14 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
283 | mr1 = 0; | 289 | mr1 = 0; |
284 | 290 | ||
285 | switch (new->c_cflag & CSIZE) { | 291 | switch (new->c_cflag & CSIZE) { |
286 | case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS; | 292 | case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS; |
287 | break; | 293 | break; |
288 | case CS6: mr1 |= MPC52xx_PSC_MODE_6_BITS; | 294 | case CS6: mr1 |= MPC52xx_PSC_MODE_6_BITS; |
289 | break; | 295 | break; |
290 | case CS7: mr1 |= MPC52xx_PSC_MODE_7_BITS; | 296 | case CS7: mr1 |= MPC52xx_PSC_MODE_7_BITS; |
291 | break; | 297 | break; |
292 | case CS8: | 298 | case CS8: |
293 | default: mr1 |= MPC52xx_PSC_MODE_8_BITS; | 299 | default: mr1 |= MPC52xx_PSC_MODE_8_BITS; |
294 | } | 300 | } |
295 | 301 | ||
296 | if (new->c_cflag & PARENB) { | 302 | if (new->c_cflag & PARENB) { |
@@ -332,24 +338,24 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
332 | udelay(1); | 338 | udelay(1); |
333 | 339 | ||
334 | if (!j) | 340 | if (!j) |
335 | printk( KERN_ERR "mpc52xx_uart.c: " | 341 | printk(KERN_ERR "mpc52xx_uart.c: " |
336 | "Unable to flush RX & TX fifos in-time in set_termios." | 342 | "Unable to flush RX & TX fifos in-time in set_termios." |
337 | "Some chars may have been lost.\n" ); | 343 | "Some chars may have been lost.\n"); |
338 | 344 | ||
339 | /* Reset the TX & RX */ | 345 | /* Reset the TX & RX */ |
340 | out_8(&psc->command,MPC52xx_PSC_RST_RX); | 346 | out_8(&psc->command, MPC52xx_PSC_RST_RX); |
341 | out_8(&psc->command,MPC52xx_PSC_RST_TX); | 347 | out_8(&psc->command, MPC52xx_PSC_RST_TX); |
342 | 348 | ||
343 | /* Send new mode settings */ | 349 | /* Send new mode settings */ |
344 | out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1); | 350 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); |
345 | out_8(&psc->mode,mr1); | 351 | out_8(&psc->mode, mr1); |
346 | out_8(&psc->mode,mr2); | 352 | out_8(&psc->mode, mr2); |
347 | out_8(&psc->ctur,ctr >> 8); | 353 | out_8(&psc->ctur, ctr >> 8); |
348 | out_8(&psc->ctlr,ctr & 0xff); | 354 | out_8(&psc->ctlr, ctr & 0xff); |
349 | 355 | ||
350 | /* Reenable TX & RX */ | 356 | /* Reenable TX & RX */ |
351 | out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); | 357 | out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); |
352 | out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); | 358 | out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); |
353 | 359 | ||
354 | /* We're all set, release the lock */ | 360 | /* We're all set, release the lock */ |
355 | spin_unlock_irqrestore(&port->lock, flags); | 361 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -364,7 +370,8 @@ mpc52xx_uart_type(struct uart_port *port) | |||
364 | static void | 370 | static void |
365 | mpc52xx_uart_release_port(struct uart_port *port) | 371 | mpc52xx_uart_release_port(struct uart_port *port) |
366 | { | 372 | { |
367 | if (port->flags & UPF_IOREMAP) { /* remapped by us ? */ | 373 | /* remapped by us ? */ |
374 | if (port->flags & UPF_IOREMAP) { | ||
368 | iounmap(port->membase); | 375 | iounmap(port->membase); |
369 | port->membase = NULL; | 376 | port->membase = NULL; |
370 | } | 377 | } |
@@ -379,7 +386,7 @@ mpc52xx_uart_request_port(struct uart_port *port) | |||
379 | 386 | ||
380 | if (port->flags & UPF_IOREMAP) /* Need to remap ? */ | 387 | if (port->flags & UPF_IOREMAP) /* Need to remap ? */ |
381 | port->membase = ioremap(port->mapbase, | 388 | port->membase = ioremap(port->mapbase, |
382 | sizeof(struct mpc52xx_psc)); | 389 | sizeof(struct mpc52xx_psc)); |
383 | 390 | ||
384 | if (!port->membase) | 391 | if (!port->membase) |
385 | return -EINVAL; | 392 | return -EINVAL; |
@@ -398,22 +405,22 @@ mpc52xx_uart_request_port(struct uart_port *port) | |||
398 | static void | 405 | static void |
399 | mpc52xx_uart_config_port(struct uart_port *port, int flags) | 406 | mpc52xx_uart_config_port(struct uart_port *port, int flags) |
400 | { | 407 | { |
401 | if ( (flags & UART_CONFIG_TYPE) && | 408 | if ((flags & UART_CONFIG_TYPE) |
402 | (mpc52xx_uart_request_port(port) == 0) ) | 409 | && (mpc52xx_uart_request_port(port) == 0)) |
403 | port->type = PORT_MPC52xx; | 410 | port->type = PORT_MPC52xx; |
404 | } | 411 | } |
405 | 412 | ||
406 | static int | 413 | static int |
407 | mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) | 414 | mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) |
408 | { | 415 | { |
409 | if ( ser->type != PORT_UNKNOWN && ser->type != PORT_MPC52xx ) | 416 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_MPC52xx) |
410 | return -EINVAL; | 417 | return -EINVAL; |
411 | 418 | ||
412 | if ( (ser->irq != port->irq) || | 419 | if ((ser->irq != port->irq) || |
413 | (ser->io_type != SERIAL_IO_MEM) || | 420 | (ser->io_type != SERIAL_IO_MEM) || |
414 | (ser->baud_base != port->uartclk) || | 421 | (ser->baud_base != port->uartclk) || |
415 | (ser->iomem_base != (void*)port->mapbase) || | 422 | (ser->iomem_base != (void *)port->mapbase) || |
416 | (ser->hub6 != 0 ) ) | 423 | (ser->hub6 != 0)) |
417 | return -EINVAL; | 424 | return -EINVAL; |
418 | 425 | ||
419 | return 0; | 426 | return 0; |
@@ -455,8 +462,8 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
455 | unsigned short status; | 462 | unsigned short status; |
456 | 463 | ||
457 | /* While we can read, do so ! */ | 464 | /* While we can read, do so ! */ |
458 | while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) & | 465 | while ((status = in_be16(&PSC(port)->mpc52xx_psc_status)) & |
459 | MPC52xx_PSC_SR_RXRDY) { | 466 | MPC52xx_PSC_SR_RXRDY) { |
460 | 467 | ||
461 | /* Get the char */ | 468 | /* Get the char */ |
462 | ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); | 469 | ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); |
@@ -474,9 +481,9 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
474 | flag = TTY_NORMAL; | 481 | flag = TTY_NORMAL; |
475 | port->icount.rx++; | 482 | port->icount.rx++; |
476 | 483 | ||
477 | if ( status & (MPC52xx_PSC_SR_PE | | 484 | if (status & (MPC52xx_PSC_SR_PE | |
478 | MPC52xx_PSC_SR_FE | | 485 | MPC52xx_PSC_SR_FE | |
479 | MPC52xx_PSC_SR_RB) ) { | 486 | MPC52xx_PSC_SR_RB)) { |
480 | 487 | ||
481 | if (status & MPC52xx_PSC_SR_RB) { | 488 | if (status & MPC52xx_PSC_SR_RB) { |
482 | flag = TTY_BREAK; | 489 | flag = TTY_BREAK; |
@@ -487,7 +494,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
487 | flag = TTY_FRAME; | 494 | flag = TTY_FRAME; |
488 | 495 | ||
489 | /* Clear error condition */ | 496 | /* Clear error condition */ |
490 | out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT); | 497 | out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); |
491 | 498 | ||
492 | } | 499 | } |
493 | tty_insert_flip_char(tty, ch, flag); | 500 | tty_insert_flip_char(tty, ch, flag); |
@@ -568,16 +575,16 @@ mpc52xx_uart_int(int irq, void *dev_id) | |||
568 | 575 | ||
569 | /* Do we need to receive chars ? */ | 576 | /* Do we need to receive chars ? */ |
570 | /* For this RX interrupts must be on and some chars waiting */ | 577 | /* For this RX interrupts must be on and some chars waiting */ |
571 | if ( status & MPC52xx_PSC_IMR_RXRDY ) | 578 | if (status & MPC52xx_PSC_IMR_RXRDY) |
572 | keepgoing |= mpc52xx_uart_int_rx_chars(port); | 579 | keepgoing |= mpc52xx_uart_int_rx_chars(port); |
573 | 580 | ||
574 | /* Do we need to send chars ? */ | 581 | /* Do we need to send chars ? */ |
575 | /* For this, TX must be ready and TX interrupt enabled */ | 582 | /* For this, TX must be ready and TX interrupt enabled */ |
576 | if ( status & MPC52xx_PSC_IMR_TXRDY ) | 583 | if (status & MPC52xx_PSC_IMR_TXRDY) |
577 | keepgoing |= mpc52xx_uart_int_tx_chars(port); | 584 | keepgoing |= mpc52xx_uart_int_tx_chars(port); |
578 | 585 | ||
579 | /* Limit number of iteration */ | 586 | /* Limit number of iteration */ |
580 | if ( !(--pass) ) | 587 | if (!(--pass)) |
581 | keepgoing = 0; | 588 | keepgoing = 0; |
582 | 589 | ||
583 | } while (keepgoing); | 590 | } while (keepgoing); |
@@ -596,7 +603,7 @@ mpc52xx_uart_int(int irq, void *dev_id) | |||
596 | 603 | ||
597 | static void __init | 604 | static void __init |
598 | mpc52xx_console_get_options(struct uart_port *port, | 605 | mpc52xx_console_get_options(struct uart_port *port, |
599 | int *baud, int *parity, int *bits, int *flow) | 606 | int *baud, int *parity, int *bits, int *flow) |
600 | { | 607 | { |
601 | struct mpc52xx_psc __iomem *psc = PSC(port); | 608 | struct mpc52xx_psc __iomem *psc = PSC(port); |
602 | unsigned char mr1; | 609 | unsigned char mr1; |
@@ -604,7 +611,7 @@ mpc52xx_console_get_options(struct uart_port *port, | |||
604 | pr_debug("mpc52xx_console_get_options(port=%p)\n", port); | 611 | pr_debug("mpc52xx_console_get_options(port=%p)\n", port); |
605 | 612 | ||
606 | /* Read the mode registers */ | 613 | /* Read the mode registers */ |
607 | out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1); | 614 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); |
608 | mr1 = in_8(&psc->mode); | 615 | mr1 = in_8(&psc->mode); |
609 | 616 | ||
610 | /* CT{U,L}R are write-only ! */ | 617 | /* CT{U,L}R are write-only ! */ |
@@ -616,11 +623,18 @@ mpc52xx_console_get_options(struct uart_port *port, | |||
616 | 623 | ||
617 | /* Parse them */ | 624 | /* Parse them */ |
618 | switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) { | 625 | switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) { |
619 | case MPC52xx_PSC_MODE_5_BITS: *bits = 5; break; | 626 | case MPC52xx_PSC_MODE_5_BITS: |
620 | case MPC52xx_PSC_MODE_6_BITS: *bits = 6; break; | 627 | *bits = 5; |
621 | case MPC52xx_PSC_MODE_7_BITS: *bits = 7; break; | 628 | break; |
622 | case MPC52xx_PSC_MODE_8_BITS: | 629 | case MPC52xx_PSC_MODE_6_BITS: |
623 | default: *bits = 8; | 630 | *bits = 6; |
631 | break; | ||
632 | case MPC52xx_PSC_MODE_7_BITS: | ||
633 | *bits = 7; | ||
634 | break; | ||
635 | case MPC52xx_PSC_MODE_8_BITS: | ||
636 | default: | ||
637 | *bits = 8; | ||
624 | } | 638 | } |
625 | 639 | ||
626 | if (mr1 & MPC52xx_PSC_MODE_PARNONE) | 640 | if (mr1 & MPC52xx_PSC_MODE_PARNONE) |
@@ -657,7 +671,7 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count) | |||
657 | /* Wait the TX buffer to be empty */ | 671 | /* Wait the TX buffer to be empty */ |
658 | j = 20000; /* Maximum wait */ | 672 | j = 20000; /* Maximum wait */ |
659 | while (!(in_be16(&psc->mpc52xx_psc_status) & | 673 | while (!(in_be16(&psc->mpc52xx_psc_status) & |
660 | MPC52xx_PSC_SR_TXEMP) && --j) | 674 | MPC52xx_PSC_SR_TXEMP) && --j) |
661 | udelay(1); | 675 | udelay(1); |
662 | } | 676 | } |
663 | 677 | ||
@@ -730,16 +744,18 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
730 | } | 744 | } |
731 | 745 | ||
732 | pr_debug("Console on ttyPSC%x is %s\n", | 746 | pr_debug("Console on ttyPSC%x is %s\n", |
733 | co->index, mpc52xx_uart_nodes[co->index]->full_name); | 747 | co->index, mpc52xx_uart_nodes[co->index]->full_name); |
734 | 748 | ||
735 | /* Fetch register locations */ | 749 | /* Fetch register locations */ |
736 | if ((ret = of_address_to_resource(np, 0, &res)) != 0) { | 750 | ret = of_address_to_resource(np, 0, &res); |
751 | if (ret) { | ||
737 | pr_debug("Could not get resources for PSC%x\n", co->index); | 752 | pr_debug("Could not get resources for PSC%x\n", co->index); |
738 | return ret; | 753 | return ret; |
739 | } | 754 | } |
740 | 755 | ||
741 | /* Search for bus-frequency property in this node or a parent */ | 756 | /* Search for bus-frequency property in this node or a parent */ |
742 | if ((ipb_freq = mpc52xx_find_ipb_freq(np)) == 0) { | 757 | ipb_freq = mpc52xx_find_ipb_freq(np); |
758 | if (ipb_freq == 0) { | ||
743 | pr_debug("Could not find IPB bus frequency!\n"); | 759 | pr_debug("Could not find IPB bus frequency!\n"); |
744 | return -EINVAL; | 760 | return -EINVAL; |
745 | } | 761 | } |
@@ -757,7 +773,8 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
757 | return -EINVAL; | 773 | return -EINVAL; |
758 | 774 | ||
759 | pr_debug("mpc52xx-psc uart at %p, mapped to %p, irq=%x, freq=%i\n", | 775 | pr_debug("mpc52xx-psc uart at %p, mapped to %p, irq=%x, freq=%i\n", |
760 | (void*)port->mapbase, port->membase, port->irq, port->uartclk); | 776 | (void *)port->mapbase, port->membase, |
777 | port->irq, port->uartclk); | ||
761 | 778 | ||
762 | /* Setup the port parameters accoding to options */ | 779 | /* Setup the port parameters accoding to options */ |
763 | if (options) | 780 | if (options) |
@@ -766,7 +783,7 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
766 | mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow); | 783 | mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow); |
767 | 784 | ||
768 | pr_debug("Setting console parameters: %i %i%c1 flow=%c\n", | 785 | pr_debug("Setting console parameters: %i %i%c1 flow=%c\n", |
769 | baud, bits, parity, flow); | 786 | baud, bits, parity, flow); |
770 | 787 | ||
771 | return uart_set_options(port, co, baud, parity, bits, flow); | 788 | return uart_set_options(port, co, baud, parity, bits, flow); |
772 | } | 789 | } |
@@ -781,7 +798,7 @@ static struct console mpc52xx_console = { | |||
781 | .device = uart_console_device, | 798 | .device = uart_console_device, |
782 | .setup = mpc52xx_console_setup, | 799 | .setup = mpc52xx_console_setup, |
783 | .flags = CON_PRINTBUFFER, | 800 | .flags = CON_PRINTBUFFER, |
784 | .index = -1, /* Specified on the cmdline (e.g. console=ttyPSC0 ) */ | 801 | .index = -1, /* Specified on the cmdline (e.g. console=ttyPSC0) */ |
785 | .data = &mpc52xx_uart_driver, | 802 | .data = &mpc52xx_uart_driver, |
786 | }; | 803 | }; |
787 | 804 | ||
@@ -809,7 +826,6 @@ console_initcall(mpc52xx_console_init); | |||
809 | /* ======================================================================== */ | 826 | /* ======================================================================== */ |
810 | 827 | ||
811 | static struct uart_driver mpc52xx_uart_driver = { | 828 | static struct uart_driver mpc52xx_uart_driver = { |
812 | .owner = THIS_MODULE, | ||
813 | .driver_name = "mpc52xx_psc_uart", | 829 | .driver_name = "mpc52xx_psc_uart", |
814 | .dev_name = "ttyPSC", | 830 | .dev_name = "ttyPSC", |
815 | .major = SERIAL_PSC_MAJOR, | 831 | .major = SERIAL_PSC_MAJOR, |
@@ -837,7 +853,7 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
837 | if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM) | 853 | if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM) |
838 | return -EINVAL; | 854 | return -EINVAL; |
839 | 855 | ||
840 | if (!mpc52xx_match_psc_function(idx,"uart")) | 856 | if (!mpc52xx_match_psc_function(idx, "uart")) |
841 | return -ENODEV; | 857 | return -ENODEV; |
842 | 858 | ||
843 | /* Init the port structure */ | 859 | /* Init the port structure */ |
@@ -848,13 +864,13 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
848 | port->fifosize = 512; | 864 | port->fifosize = 512; |
849 | port->iotype = UPIO_MEM; | 865 | port->iotype = UPIO_MEM; |
850 | port->flags = UPF_BOOT_AUTOCONF | | 866 | port->flags = UPF_BOOT_AUTOCONF | |
851 | ( uart_console(port) ? 0 : UPF_IOREMAP ); | 867 | (uart_console(port) ? 0 : UPF_IOREMAP); |
852 | port->line = idx; | 868 | port->line = idx; |
853 | port->ops = &mpc52xx_uart_ops; | 869 | port->ops = &mpc52xx_uart_ops; |
854 | port->dev = &dev->dev; | 870 | port->dev = &dev->dev; |
855 | 871 | ||
856 | /* Search for IRQ and mapbase */ | 872 | /* Search for IRQ and mapbase */ |
857 | for (i=0 ; i<dev->num_resources ; i++, res++) { | 873 | for (i = 0 ; i < dev->num_resources ; i++, res++) { |
858 | if (res->flags & IORESOURCE_MEM) | 874 | if (res->flags & IORESOURCE_MEM) |
859 | port->mapbase = res->start; | 875 | port->mapbase = res->start; |
860 | else if (res->flags & IORESOURCE_IRQ) | 876 | else if (res->flags & IORESOURCE_IRQ) |
@@ -866,7 +882,7 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
866 | /* Add the port to the uart sub-system */ | 882 | /* Add the port to the uart sub-system */ |
867 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); | 883 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); |
868 | if (!ret) | 884 | if (!ret) |
869 | platform_set_drvdata(dev, (void*)port); | 885 | platform_set_drvdata(dev, (void *)port); |
870 | 886 | ||
871 | return ret; | 887 | return ret; |
872 | } | 888 | } |
@@ -917,6 +933,7 @@ static struct platform_driver mpc52xx_uart_platform_driver = { | |||
917 | .resume = mpc52xx_uart_resume, | 933 | .resume = mpc52xx_uart_resume, |
918 | #endif | 934 | #endif |
919 | .driver = { | 935 | .driver = { |
936 | .owner = THIS_MODULE, | ||
920 | .name = "mpc52xx-psc", | 937 | .name = "mpc52xx-psc", |
921 | }, | 938 | }, |
922 | }; | 939 | }; |
@@ -946,10 +963,11 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
946 | if (idx >= MPC52xx_PSC_MAXNUM) | 963 | if (idx >= MPC52xx_PSC_MAXNUM) |
947 | return -EINVAL; | 964 | return -EINVAL; |
948 | pr_debug("Found %s assigned to ttyPSC%x\n", | 965 | pr_debug("Found %s assigned to ttyPSC%x\n", |
949 | mpc52xx_uart_nodes[idx]->full_name, idx); | 966 | mpc52xx_uart_nodes[idx]->full_name, idx); |
950 | 967 | ||
951 | /* Search for bus-frequency property in this node or a parent */ | 968 | /* Search for bus-frequency property in this node or a parent */ |
952 | if ((ipb_freq = mpc52xx_find_ipb_freq(op->node)) == 0) { | 969 | ipb_freq = mpc52xx_find_ipb_freq(op->node); |
970 | if (ipb_freq == 0) { | ||
953 | dev_dbg(&op->dev, "Could not find IPB bus frequency!\n"); | 971 | dev_dbg(&op->dev, "Could not find IPB bus frequency!\n"); |
954 | return -EINVAL; | 972 | return -EINVAL; |
955 | } | 973 | } |
@@ -962,22 +980,23 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
962 | port->fifosize = 512; | 980 | port->fifosize = 512; |
963 | port->iotype = UPIO_MEM; | 981 | port->iotype = UPIO_MEM; |
964 | port->flags = UPF_BOOT_AUTOCONF | | 982 | port->flags = UPF_BOOT_AUTOCONF | |
965 | ( uart_console(port) ? 0 : UPF_IOREMAP ); | 983 | (uart_console(port) ? 0 : UPF_IOREMAP); |
966 | port->line = idx; | 984 | port->line = idx; |
967 | port->ops = &mpc52xx_uart_ops; | 985 | port->ops = &mpc52xx_uart_ops; |
968 | port->dev = &op->dev; | 986 | port->dev = &op->dev; |
969 | 987 | ||
970 | /* Search for IRQ and mapbase */ | 988 | /* Search for IRQ and mapbase */ |
971 | if ((ret = of_address_to_resource(op->node, 0, &res)) != 0) | 989 | ret = of_address_to_resource(op->node, 0, &res); |
990 | if (ret) | ||
972 | return ret; | 991 | return ret; |
973 | 992 | ||
974 | port->mapbase = res.start; | 993 | port->mapbase = res.start; |
975 | port->irq = irq_of_parse_and_map(op->node, 0); | 994 | port->irq = irq_of_parse_and_map(op->node, 0); |
976 | 995 | ||
977 | dev_dbg(&op->dev, "mpc52xx-psc uart at %p, irq=%x, freq=%i\n", | 996 | dev_dbg(&op->dev, "mpc52xx-psc uart at %p, irq=%x, freq=%i\n", |
978 | (void*)port->mapbase, port->irq, port->uartclk); | 997 | (void *)port->mapbase, port->irq, port->uartclk); |
979 | 998 | ||
980 | if ((port->irq==NO_IRQ) || !port->mapbase) { | 999 | if ((port->irq == NO_IRQ) || !port->mapbase) { |
981 | printk(KERN_ERR "Could not allocate resources for PSC\n"); | 1000 | printk(KERN_ERR "Could not allocate resources for PSC\n"); |
982 | return -EINVAL; | 1001 | return -EINVAL; |
983 | } | 1002 | } |
@@ -985,7 +1004,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
985 | /* Add the port to the uart sub-system */ | 1004 | /* Add the port to the uart sub-system */ |
986 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); | 1005 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); |
987 | if (!ret) | 1006 | if (!ret) |
988 | dev_set_drvdata(&op->dev, (void*)port); | 1007 | dev_set_drvdata(&op->dev, (void *)port); |
989 | 1008 | ||
990 | return ret; | 1009 | return ret; |
991 | } | 1010 | } |
@@ -1048,6 +1067,7 @@ mpc52xx_uart_of_assign(struct device_node *np, int idx) | |||
1048 | if (idx < 0) | 1067 | if (idx < 0) |
1049 | return; /* No free slot; abort */ | 1068 | return; /* No free slot; abort */ |
1050 | 1069 | ||
1070 | of_node_get(np); | ||
1051 | /* If the slot is already occupied, then swap slots */ | 1071 | /* If the slot is already occupied, then swap slots */ |
1052 | if (mpc52xx_uart_nodes[idx] && (free_idx != -1)) | 1072 | if (mpc52xx_uart_nodes[idx] && (free_idx != -1)) |
1053 | mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx]; | 1073 | mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx]; |
@@ -1057,7 +1077,7 @@ mpc52xx_uart_of_assign(struct device_node *np, int idx) | |||
1057 | static void | 1077 | static void |
1058 | mpc52xx_uart_of_enumerate(void) | 1078 | mpc52xx_uart_of_enumerate(void) |
1059 | { | 1079 | { |
1060 | static int enum_done = 0; | 1080 | static int enum_done; |
1061 | struct device_node *np; | 1081 | struct device_node *np; |
1062 | const unsigned int *devno; | 1082 | const unsigned int *devno; |
1063 | int i; | 1083 | int i; |
@@ -1071,7 +1091,7 @@ mpc52xx_uart_of_enumerate(void) | |||
1071 | 1091 | ||
1072 | /* Is a particular device number requested? */ | 1092 | /* Is a particular device number requested? */ |
1073 | devno = of_get_property(np, "port-number", NULL); | 1093 | devno = of_get_property(np, "port-number", NULL); |
1074 | mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1); | 1094 | mpc52xx_uart_of_assign(np, devno ? *devno : -1); |
1075 | } | 1095 | } |
1076 | 1096 | ||
1077 | enum_done = 1; | 1097 | enum_done = 1; |
@@ -1079,15 +1099,13 @@ mpc52xx_uart_of_enumerate(void) | |||
1079 | for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { | 1099 | for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { |
1080 | if (mpc52xx_uart_nodes[i]) | 1100 | if (mpc52xx_uart_nodes[i]) |
1081 | pr_debug("%s assigned to ttyPSC%x\n", | 1101 | pr_debug("%s assigned to ttyPSC%x\n", |
1082 | mpc52xx_uart_nodes[i]->full_name, i); | 1102 | mpc52xx_uart_nodes[i]->full_name, i); |
1083 | } | 1103 | } |
1084 | } | 1104 | } |
1085 | 1105 | ||
1086 | MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); | 1106 | MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); |
1087 | 1107 | ||
1088 | static struct of_platform_driver mpc52xx_uart_of_driver = { | 1108 | static struct of_platform_driver mpc52xx_uart_of_driver = { |
1089 | .owner = THIS_MODULE, | ||
1090 | .name = "mpc52xx-psc-uart", | ||
1091 | .match_table = mpc52xx_uart_of_match, | 1109 | .match_table = mpc52xx_uart_of_match, |
1092 | .probe = mpc52xx_uart_of_probe, | 1110 | .probe = mpc52xx_uart_of_probe, |
1093 | .remove = mpc52xx_uart_of_remove, | 1111 | .remove = mpc52xx_uart_of_remove, |
@@ -1113,7 +1131,8 @@ mpc52xx_uart_init(void) | |||
1113 | 1131 | ||
1114 | printk(KERN_INFO "Serial: MPC52xx PSC UART driver\n"); | 1132 | printk(KERN_INFO "Serial: MPC52xx PSC UART driver\n"); |
1115 | 1133 | ||
1116 | if ((ret = uart_register_driver(&mpc52xx_uart_driver)) != 0) { | 1134 | ret = uart_register_driver(&mpc52xx_uart_driver); |
1135 | if (ret) { | ||
1117 | printk(KERN_ERR "%s: uart_register_driver failed (%i)\n", | 1136 | printk(KERN_ERR "%s: uart_register_driver failed (%i)\n", |
1118 | __FILE__, ret); | 1137 | __FILE__, ret); |
1119 | return ret; | 1138 | return ret; |
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 3f593247c41e..80943409edb0 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c | |||
@@ -539,7 +539,7 @@ static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq) | |||
539 | * | 539 | * |
540 | * @dev: pointer to device structure | 540 | * @dev: pointer to device structure |
541 | */ | 541 | */ |
542 | static int __devinit ulite_release(struct device *dev) | 542 | static int __devexit ulite_release(struct device *dev) |
543 | { | 543 | { |
544 | struct uart_port *port = dev_get_drvdata(dev); | 544 | struct uart_port *port = dev_get_drvdata(dev); |
545 | int rc = 0; | 545 | int rc = 0; |
@@ -572,14 +572,14 @@ static int __devinit ulite_probe(struct platform_device *pdev) | |||
572 | return ulite_assign(&pdev->dev, pdev->id, res->start, res2->start); | 572 | return ulite_assign(&pdev->dev, pdev->id, res->start, res2->start); |
573 | } | 573 | } |
574 | 574 | ||
575 | static int ulite_remove(struct platform_device *pdev) | 575 | static int __devexit ulite_remove(struct platform_device *pdev) |
576 | { | 576 | { |
577 | return ulite_release(&pdev->dev); | 577 | return ulite_release(&pdev->dev); |
578 | } | 578 | } |
579 | 579 | ||
580 | static struct platform_driver ulite_platform_driver = { | 580 | static struct platform_driver ulite_platform_driver = { |
581 | .probe = ulite_probe, | 581 | .probe = ulite_probe, |
582 | .remove = ulite_remove, | 582 | .remove = __devexit_p(ulite_remove), |
583 | .driver = { | 583 | .driver = { |
584 | .owner = THIS_MODULE, | 584 | .owner = THIS_MODULE, |
585 | .name = "uartlite", | 585 | .name = "uartlite", |
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c new file mode 100644 index 000000000000..e0994f061001 --- /dev/null +++ b/drivers/serial/ucc_uart.c | |||
@@ -0,0 +1,1514 @@ | |||
1 | /* | ||
2 | * Freescale QUICC Engine UART device driver | ||
3 | * | ||
4 | * Author: Timur Tabi <timur@freescale.com> | ||
5 | * | ||
6 | * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | * | ||
11 | * This driver adds support for UART devices via Freescale's QUICC Engine | ||
12 | * found on some Freescale SOCs. | ||
13 | * | ||
14 | * If Soft-UART support is needed but not already present, then this driver | ||
15 | * will request and upload the "Soft-UART" microcode upon probe. The | ||
16 | * filename of the microcode should be fsl_qe_ucode_uart_X_YZ.bin, where "X" | ||
17 | * is the name of the SOC (e.g. 8323), and YZ is the revision of the SOC, | ||
18 | * (e.g. "11" for 1.1). | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/serial.h> | ||
23 | #include <linux/serial_core.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/of_platform.h> | ||
26 | #include <linux/dma-mapping.h> | ||
27 | |||
28 | #include <linux/fs_uart_pd.h> | ||
29 | #include <asm/ucc_slow.h> | ||
30 | |||
31 | #include <linux/firmware.h> | ||
32 | #include <asm/reg.h> | ||
33 | |||
34 | /* | ||
35 | * The GUMR flag for Soft UART. This would normally be defined in qe.h, | ||
36 | * but Soft-UART is a hack and we want to keep everything related to it in | ||
37 | * this file. | ||
38 | */ | ||
39 | #define UCC_SLOW_GUMR_H_SUART 0x00004000 /* Soft-UART */ | ||
40 | |||
41 | /* | ||
42 | * soft_uart is 1 if we need to use Soft-UART mode | ||
43 | */ | ||
44 | static int soft_uart; | ||
45 | /* | ||
46 | * firmware_loaded is 1 if the firmware has been loaded, 0 otherwise. | ||
47 | */ | ||
48 | static int firmware_loaded; | ||
49 | |||
50 | /* Enable this macro to configure all serial ports in internal loopback | ||
51 | mode */ | ||
52 | /* #define LOOPBACK */ | ||
53 | |||
54 | /* The major and minor device numbers are defined in | ||
55 | * http://www.lanana.org/docs/device-list/devices-2.6+.txt. For the QE | ||
56 | * UART, we have major number 204 and minor numbers 46 - 49, which are the | ||
57 | * same as for the CPM2. This decision was made because no Freescale part | ||
58 | * has both a CPM and a QE. | ||
59 | */ | ||
60 | #define SERIAL_QE_MAJOR 204 | ||
61 | #define SERIAL_QE_MINOR 46 | ||
62 | |||
63 | /* Since we only have minor numbers 46 - 49, there is a hard limit of 4 ports */ | ||
64 | #define UCC_MAX_UART 4 | ||
65 | |||
66 | /* The number of buffer descriptors for receiving characters. */ | ||
67 | #define RX_NUM_FIFO 4 | ||
68 | |||
69 | /* The number of buffer descriptors for transmitting characters. */ | ||
70 | #define TX_NUM_FIFO 4 | ||
71 | |||
72 | /* The maximum size of the character buffer for a single RX BD. */ | ||
73 | #define RX_BUF_SIZE 32 | ||
74 | |||
75 | /* The maximum size of the character buffer for a single TX BD. */ | ||
76 | #define TX_BUF_SIZE 32 | ||
77 | |||
78 | /* | ||
79 | * The number of jiffies to wait after receiving a close command before the | ||
80 | * device is actually closed. This allows the last few characters to be | ||
81 | * sent over the wire. | ||
82 | */ | ||
83 | #define UCC_WAIT_CLOSING 100 | ||
84 | |||
85 | struct ucc_uart_pram { | ||
86 | struct ucc_slow_pram common; | ||
87 | u8 res1[8]; /* reserved */ | ||
88 | __be16 maxidl; /* Maximum idle chars */ | ||
89 | __be16 idlc; /* temp idle counter */ | ||
90 | __be16 brkcr; /* Break count register */ | ||
91 | __be16 parec; /* receive parity error counter */ | ||
92 | __be16 frmec; /* receive framing error counter */ | ||
93 | __be16 nosec; /* receive noise counter */ | ||
94 | __be16 brkec; /* receive break condition counter */ | ||
95 | __be16 brkln; /* last received break length */ | ||
96 | __be16 uaddr[2]; /* UART address character 1 & 2 */ | ||
97 | __be16 rtemp; /* Temp storage */ | ||
98 | __be16 toseq; /* Transmit out of sequence char */ | ||
99 | __be16 cchars[8]; /* control characters 1-8 */ | ||
100 | __be16 rccm; /* receive control character mask */ | ||
101 | __be16 rccr; /* receive control character register */ | ||
102 | __be16 rlbc; /* receive last break character */ | ||
103 | __be16 res2; /* reserved */ | ||
104 | __be32 res3; /* reserved, should be cleared */ | ||
105 | u8 res4; /* reserved, should be cleared */ | ||
106 | u8 res5[3]; /* reserved, should be cleared */ | ||
107 | __be32 res6; /* reserved, should be cleared */ | ||
108 | __be32 res7; /* reserved, should be cleared */ | ||
109 | __be32 res8; /* reserved, should be cleared */ | ||
110 | __be32 res9; /* reserved, should be cleared */ | ||
111 | __be32 res10; /* reserved, should be cleared */ | ||
112 | __be32 res11; /* reserved, should be cleared */ | ||
113 | __be32 res12; /* reserved, should be cleared */ | ||
114 | __be32 res13; /* reserved, should be cleared */ | ||
115 | /* The rest is for Soft-UART only */ | ||
116 | __be16 supsmr; /* 0x90, Shadow UPSMR */ | ||
117 | __be16 res92; /* 0x92, reserved, initialize to 0 */ | ||
118 | __be32 rx_state; /* 0x94, RX state, initialize to 0 */ | ||
119 | __be32 rx_cnt; /* 0x98, RX count, initialize to 0 */ | ||
120 | u8 rx_length; /* 0x9C, Char length, set to 1+CL+PEN+1+SL */ | ||
121 | u8 rx_bitmark; /* 0x9D, reserved, initialize to 0 */ | ||
122 | u8 rx_temp_dlst_qe; /* 0x9E, reserved, initialize to 0 */ | ||
123 | u8 res14[0xBC - 0x9F]; /* reserved */ | ||
124 | __be32 dump_ptr; /* 0xBC, Dump pointer */ | ||
125 | __be32 rx_frame_rem; /* 0xC0, reserved, initialize to 0 */ | ||
126 | u8 rx_frame_rem_size; /* 0xC4, reserved, initialize to 0 */ | ||
127 | u8 tx_mode; /* 0xC5, mode, 0=AHDLC, 1=UART */ | ||
128 | __be16 tx_state; /* 0xC6, TX state */ | ||
129 | u8 res15[0xD0 - 0xC8]; /* reserved */ | ||
130 | __be32 resD0; /* 0xD0, reserved, initialize to 0 */ | ||
131 | u8 resD4; /* 0xD4, reserved, initialize to 0 */ | ||
132 | __be16 resD5; /* 0xD5, reserved, initialize to 0 */ | ||
133 | } __attribute__ ((packed)); | ||
134 | |||
135 | /* SUPSMR definitions, for Soft-UART only */ | ||
136 | #define UCC_UART_SUPSMR_SL 0x8000 | ||
137 | #define UCC_UART_SUPSMR_RPM_MASK 0x6000 | ||
138 | #define UCC_UART_SUPSMR_RPM_ODD 0x0000 | ||
139 | #define UCC_UART_SUPSMR_RPM_LOW 0x2000 | ||
140 | #define UCC_UART_SUPSMR_RPM_EVEN 0x4000 | ||
141 | #define UCC_UART_SUPSMR_RPM_HIGH 0x6000 | ||
142 | #define UCC_UART_SUPSMR_PEN 0x1000 | ||
143 | #define UCC_UART_SUPSMR_TPM_MASK 0x0C00 | ||
144 | #define UCC_UART_SUPSMR_TPM_ODD 0x0000 | ||
145 | #define UCC_UART_SUPSMR_TPM_LOW 0x0400 | ||
146 | #define UCC_UART_SUPSMR_TPM_EVEN 0x0800 | ||
147 | #define UCC_UART_SUPSMR_TPM_HIGH 0x0C00 | ||
148 | #define UCC_UART_SUPSMR_FRZ 0x0100 | ||
149 | #define UCC_UART_SUPSMR_UM_MASK 0x00c0 | ||
150 | #define UCC_UART_SUPSMR_UM_NORMAL 0x0000 | ||
151 | #define UCC_UART_SUPSMR_UM_MAN_MULTI 0x0040 | ||
152 | #define UCC_UART_SUPSMR_UM_AUTO_MULTI 0x00c0 | ||
153 | #define UCC_UART_SUPSMR_CL_MASK 0x0030 | ||
154 | #define UCC_UART_SUPSMR_CL_8 0x0030 | ||
155 | #define UCC_UART_SUPSMR_CL_7 0x0020 | ||
156 | #define UCC_UART_SUPSMR_CL_6 0x0010 | ||
157 | #define UCC_UART_SUPSMR_CL_5 0x0000 | ||
158 | |||
159 | #define UCC_UART_TX_STATE_AHDLC 0x00 | ||
160 | #define UCC_UART_TX_STATE_UART 0x01 | ||
161 | #define UCC_UART_TX_STATE_X1 0x00 | ||
162 | #define UCC_UART_TX_STATE_X16 0x80 | ||
163 | |||
164 | #define UCC_UART_PRAM_ALIGNMENT 0x100 | ||
165 | |||
166 | #define UCC_UART_SIZE_OF_BD UCC_SLOW_SIZE_OF_BD | ||
167 | #define NUM_CONTROL_CHARS 8 | ||
168 | |||
169 | /* Private per-port data structure */ | ||
170 | struct uart_qe_port { | ||
171 | struct uart_port port; | ||
172 | struct ucc_slow __iomem *uccp; | ||
173 | struct ucc_uart_pram __iomem *uccup; | ||
174 | struct ucc_slow_info us_info; | ||
175 | struct ucc_slow_private *us_private; | ||
176 | struct device_node *np; | ||
177 | unsigned int ucc_num; /* First ucc is 0, not 1 */ | ||
178 | |||
179 | u16 rx_nrfifos; | ||
180 | u16 rx_fifosize; | ||
181 | u16 tx_nrfifos; | ||
182 | u16 tx_fifosize; | ||
183 | int wait_closing; | ||
184 | u32 flags; | ||
185 | struct qe_bd *rx_bd_base; | ||
186 | struct qe_bd *rx_cur; | ||
187 | struct qe_bd *tx_bd_base; | ||
188 | struct qe_bd *tx_cur; | ||
189 | unsigned char *tx_buf; | ||
190 | unsigned char *rx_buf; | ||
191 | void *bd_virt; /* virtual address of the BD buffers */ | ||
192 | dma_addr_t bd_dma_addr; /* bus address of the BD buffers */ | ||
193 | unsigned int bd_size; /* size of BD buffer space */ | ||
194 | }; | ||
195 | |||
196 | static struct uart_driver ucc_uart_driver = { | ||
197 | .owner = THIS_MODULE, | ||
198 | .driver_name = "serial", | ||
199 | .dev_name = "ttyQE", | ||
200 | .major = SERIAL_QE_MAJOR, | ||
201 | .minor = SERIAL_QE_MINOR, | ||
202 | .nr = UCC_MAX_UART, | ||
203 | }; | ||
204 | |||
205 | /* | ||
206 | * Virtual to physical address translation. | ||
207 | * | ||
208 | * Given the virtual address for a character buffer, this function returns | ||
209 | * the physical (DMA) equivalent. | ||
210 | */ | ||
211 | static inline dma_addr_t cpu2qe_addr(void *addr, struct uart_qe_port *qe_port) | ||
212 | { | ||
213 | if (likely((addr >= qe_port->bd_virt)) && | ||
214 | (addr < (qe_port->bd_virt + qe_port->bd_size))) | ||
215 | return qe_port->bd_dma_addr + (addr - qe_port->bd_virt); | ||
216 | |||
217 | /* something nasty happened */ | ||
218 | printk(KERN_ERR "%s: addr=%p\n", __FUNCTION__, addr); | ||
219 | BUG(); | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Physical to virtual address translation. | ||
225 | * | ||
226 | * Given the physical (DMA) address for a character buffer, this function | ||
227 | * returns the virtual equivalent. | ||
228 | */ | ||
229 | static inline void *qe2cpu_addr(dma_addr_t addr, struct uart_qe_port *qe_port) | ||
230 | { | ||
231 | /* sanity check */ | ||
232 | if (likely((addr >= qe_port->bd_dma_addr) && | ||
233 | (addr < (qe_port->bd_dma_addr + qe_port->bd_size)))) | ||
234 | return qe_port->bd_virt + (addr - qe_port->bd_dma_addr); | ||
235 | |||
236 | /* something nasty happened */ | ||
237 | printk(KERN_ERR "%s: addr=%x\n", __FUNCTION__, addr); | ||
238 | BUG(); | ||
239 | return NULL; | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * Return 1 if the QE is done transmitting all buffers for this port | ||
244 | * | ||
245 | * This function scans each BD in sequence. If we find a BD that is not | ||
246 | * ready (READY=1), then we return 0 indicating that the QE is still sending | ||
247 | * data. If we reach the last BD (WRAP=1), then we know we've scanned | ||
248 | * the entire list, and all BDs are done. | ||
249 | */ | ||
250 | static unsigned int qe_uart_tx_empty(struct uart_port *port) | ||
251 | { | ||
252 | struct uart_qe_port *qe_port = | ||
253 | container_of(port, struct uart_qe_port, port); | ||
254 | struct qe_bd *bdp = qe_port->tx_bd_base; | ||
255 | |||
256 | while (1) { | ||
257 | if (in_be16(&bdp->status) & BD_SC_READY) | ||
258 | /* This BD is not done, so return "not done" */ | ||
259 | return 0; | ||
260 | |||
261 | if (in_be16(&bdp->status) & BD_SC_WRAP) | ||
262 | /* | ||
263 | * This BD is done and it's the last one, so return | ||
264 | * "done" | ||
265 | */ | ||
266 | return 1; | ||
267 | |||
268 | bdp++; | ||
269 | }; | ||
270 | } | ||
271 | |||
272 | /* | ||
273 | * Set the modem control lines | ||
274 | * | ||
275 | * Although the QE can control the modem control lines (e.g. CTS), we | ||
276 | * don't need that support. This function must exist, however, otherwise | ||
277 | * the kernel will panic. | ||
278 | */ | ||
279 | void qe_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
280 | { | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * Get the current modem control line status | ||
285 | * | ||
286 | * Although the QE can control the modem control lines (e.g. CTS), this | ||
287 | * driver currently doesn't support that, so we always return Carrier | ||
288 | * Detect, Data Set Ready, and Clear To Send. | ||
289 | */ | ||
290 | static unsigned int qe_uart_get_mctrl(struct uart_port *port) | ||
291 | { | ||
292 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Disable the transmit interrupt. | ||
297 | * | ||
298 | * Although this function is called "stop_tx", it does not actually stop | ||
299 | * transmission of data. Instead, it tells the QE to not generate an | ||
300 | * interrupt when the UCC is finished sending characters. | ||
301 | */ | ||
302 | static void qe_uart_stop_tx(struct uart_port *port) | ||
303 | { | ||
304 | struct uart_qe_port *qe_port = | ||
305 | container_of(port, struct uart_qe_port, port); | ||
306 | |||
307 | clrbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX); | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * Transmit as many characters to the HW as possible. | ||
312 | * | ||
313 | * This function will attempt to stuff of all the characters from the | ||
314 | * kernel's transmit buffer into TX BDs. | ||
315 | * | ||
316 | * A return value of non-zero indicates that it sucessfully stuffed all | ||
317 | * characters from the kernel buffer. | ||
318 | * | ||
319 | * A return value of zero indicates that there are still characters in the | ||
320 | * kernel's buffer that have not been transmitted, but there are no more BDs | ||
321 | * available. This function should be called again after a BD has been made | ||
322 | * available. | ||
323 | */ | ||
324 | static int qe_uart_tx_pump(struct uart_qe_port *qe_port) | ||
325 | { | ||
326 | struct qe_bd *bdp; | ||
327 | unsigned char *p; | ||
328 | unsigned int count; | ||
329 | struct uart_port *port = &qe_port->port; | ||
330 | struct circ_buf *xmit = &port->info->xmit; | ||
331 | |||
332 | bdp = qe_port->rx_cur; | ||
333 | |||
334 | /* Handle xon/xoff */ | ||
335 | if (port->x_char) { | ||
336 | /* Pick next descriptor and fill from buffer */ | ||
337 | bdp = qe_port->tx_cur; | ||
338 | |||
339 | p = qe2cpu_addr(bdp->buf, qe_port); | ||
340 | |||
341 | *p++ = port->x_char; | ||
342 | out_be16(&bdp->length, 1); | ||
343 | setbits16(&bdp->status, BD_SC_READY); | ||
344 | /* Get next BD. */ | ||
345 | if (in_be16(&bdp->status) & BD_SC_WRAP) | ||
346 | bdp = qe_port->tx_bd_base; | ||
347 | else | ||
348 | bdp++; | ||
349 | qe_port->tx_cur = bdp; | ||
350 | |||
351 | port->icount.tx++; | ||
352 | port->x_char = 0; | ||
353 | return 1; | ||
354 | } | ||
355 | |||
356 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
357 | qe_uart_stop_tx(port); | ||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | /* Pick next descriptor and fill from buffer */ | ||
362 | bdp = qe_port->tx_cur; | ||
363 | |||
364 | while (!(in_be16(&bdp->status) & BD_SC_READY) && | ||
365 | (xmit->tail != xmit->head)) { | ||
366 | count = 0; | ||
367 | p = qe2cpu_addr(bdp->buf, qe_port); | ||
368 | while (count < qe_port->tx_fifosize) { | ||
369 | *p++ = xmit->buf[xmit->tail]; | ||
370 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
371 | port->icount.tx++; | ||
372 | count++; | ||
373 | if (xmit->head == xmit->tail) | ||
374 | break; | ||
375 | } | ||
376 | |||
377 | out_be16(&bdp->length, count); | ||
378 | setbits16(&bdp->status, BD_SC_READY); | ||
379 | |||
380 | /* Get next BD. */ | ||
381 | if (in_be16(&bdp->status) & BD_SC_WRAP) | ||
382 | bdp = qe_port->tx_bd_base; | ||
383 | else | ||
384 | bdp++; | ||
385 | } | ||
386 | qe_port->tx_cur = bdp; | ||
387 | |||
388 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
389 | uart_write_wakeup(port); | ||
390 | |||
391 | if (uart_circ_empty(xmit)) { | ||
392 | /* The kernel buffer is empty, so turn off TX interrupts. We | ||
393 | don't need to be told when the QE is finished transmitting | ||
394 | the data. */ | ||
395 | qe_uart_stop_tx(port); | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | return 1; | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * Start transmitting data | ||
404 | * | ||
405 | * This function will start transmitting any available data, if the port | ||
406 | * isn't already transmitting data. | ||
407 | */ | ||
408 | static void qe_uart_start_tx(struct uart_port *port) | ||
409 | { | ||
410 | struct uart_qe_port *qe_port = | ||
411 | container_of(port, struct uart_qe_port, port); | ||
412 | |||
413 | /* If we currently are transmitting, then just return */ | ||
414 | if (in_be16(&qe_port->uccp->uccm) & UCC_UART_UCCE_TX) | ||
415 | return; | ||
416 | |||
417 | /* Otherwise, pump the port and start transmission */ | ||
418 | if (qe_uart_tx_pump(qe_port)) | ||
419 | setbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX); | ||
420 | } | ||
421 | |||
422 | /* | ||
423 | * Stop transmitting data | ||
424 | */ | ||
425 | static void qe_uart_stop_rx(struct uart_port *port) | ||
426 | { | ||
427 | struct uart_qe_port *qe_port = | ||
428 | container_of(port, struct uart_qe_port, port); | ||
429 | |||
430 | clrbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX); | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | * Enable status change interrupts | ||
435 | * | ||
436 | * We don't support status change interrupts, but we need to define this | ||
437 | * function otherwise the kernel will panic. | ||
438 | */ | ||
439 | static void qe_uart_enable_ms(struct uart_port *port) | ||
440 | { | ||
441 | } | ||
442 | |||
443 | /* Start or stop sending break signal | ||
444 | * | ||
445 | * This function controls the sending of a break signal. If break_state=1, | ||
446 | * then we start sending a break signal. If break_state=0, then we stop | ||
447 | * sending the break signal. | ||
448 | */ | ||
449 | static void qe_uart_break_ctl(struct uart_port *port, int break_state) | ||
450 | { | ||
451 | struct uart_qe_port *qe_port = | ||
452 | container_of(port, struct uart_qe_port, port); | ||
453 | |||
454 | if (break_state) | ||
455 | ucc_slow_stop_tx(qe_port->us_private); | ||
456 | else | ||
457 | ucc_slow_restart_tx(qe_port->us_private); | ||
458 | } | ||
459 | |||
460 | /* ISR helper function for receiving character. | ||
461 | * | ||
462 | * This function is called by the ISR to handling receiving characters | ||
463 | */ | ||
464 | static void qe_uart_int_rx(struct uart_qe_port *qe_port) | ||
465 | { | ||
466 | int i; | ||
467 | unsigned char ch, *cp; | ||
468 | struct uart_port *port = &qe_port->port; | ||
469 | struct tty_struct *tty = port->info->tty; | ||
470 | struct qe_bd *bdp; | ||
471 | u16 status; | ||
472 | unsigned int flg; | ||
473 | |||
474 | /* Just loop through the closed BDs and copy the characters into | ||
475 | * the buffer. | ||
476 | */ | ||
477 | bdp = qe_port->rx_cur; | ||
478 | while (1) { | ||
479 | status = in_be16(&bdp->status); | ||
480 | |||
481 | /* If this one is empty, then we assume we've read them all */ | ||
482 | if (status & BD_SC_EMPTY) | ||
483 | break; | ||
484 | |||
485 | /* get number of characters, and check space in RX buffer */ | ||
486 | i = in_be16(&bdp->length); | ||
487 | |||
488 | /* If we don't have enough room in RX buffer for the entire BD, | ||
489 | * then we try later, which will be the next RX interrupt. | ||
490 | */ | ||
491 | if (tty_buffer_request_room(tty, i) < i) { | ||
492 | dev_dbg(port->dev, "ucc-uart: no room in RX buffer\n"); | ||
493 | return; | ||
494 | } | ||
495 | |||
496 | /* get pointer */ | ||
497 | cp = qe2cpu_addr(bdp->buf, qe_port); | ||
498 | |||
499 | /* loop through the buffer */ | ||
500 | while (i-- > 0) { | ||
501 | ch = *cp++; | ||
502 | port->icount.rx++; | ||
503 | flg = TTY_NORMAL; | ||
504 | |||
505 | if (!i && status & | ||
506 | (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV)) | ||
507 | goto handle_error; | ||
508 | if (uart_handle_sysrq_char(port, ch)) | ||
509 | continue; | ||
510 | |||
511 | error_return: | ||
512 | tty_insert_flip_char(tty, ch, flg); | ||
513 | |||
514 | } | ||
515 | |||
516 | /* This BD is ready to be used again. Clear status. get next */ | ||
517 | clrsetbits_be16(&bdp->status, BD_SC_BR | BD_SC_FR | BD_SC_PR | | ||
518 | BD_SC_OV | BD_SC_ID, BD_SC_EMPTY); | ||
519 | if (in_be16(&bdp->status) & BD_SC_WRAP) | ||
520 | bdp = qe_port->rx_bd_base; | ||
521 | else | ||
522 | bdp++; | ||
523 | |||
524 | } | ||
525 | |||
526 | /* Write back buffer pointer */ | ||
527 | qe_port->rx_cur = bdp; | ||
528 | |||
529 | /* Activate BH processing */ | ||
530 | tty_flip_buffer_push(tty); | ||
531 | |||
532 | return; | ||
533 | |||
534 | /* Error processing */ | ||
535 | |||
536 | handle_error: | ||
537 | /* Statistics */ | ||
538 | if (status & BD_SC_BR) | ||
539 | port->icount.brk++; | ||
540 | if (status & BD_SC_PR) | ||
541 | port->icount.parity++; | ||
542 | if (status & BD_SC_FR) | ||
543 | port->icount.frame++; | ||
544 | if (status & BD_SC_OV) | ||
545 | port->icount.overrun++; | ||
546 | |||
547 | /* Mask out ignored conditions */ | ||
548 | status &= port->read_status_mask; | ||
549 | |||
550 | /* Handle the remaining ones */ | ||
551 | if (status & BD_SC_BR) | ||
552 | flg = TTY_BREAK; | ||
553 | else if (status & BD_SC_PR) | ||
554 | flg = TTY_PARITY; | ||
555 | else if (status & BD_SC_FR) | ||
556 | flg = TTY_FRAME; | ||
557 | |||
558 | /* Overrun does not affect the current character ! */ | ||
559 | if (status & BD_SC_OV) | ||
560 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
561 | #ifdef SUPPORT_SYSRQ | ||
562 | port->sysrq = 0; | ||
563 | #endif | ||
564 | goto error_return; | ||
565 | } | ||
566 | |||
567 | /* Interrupt handler | ||
568 | * | ||
569 | * This interrupt handler is called after a BD is processed. | ||
570 | */ | ||
571 | static irqreturn_t qe_uart_int(int irq, void *data) | ||
572 | { | ||
573 | struct uart_qe_port *qe_port = (struct uart_qe_port *) data; | ||
574 | struct ucc_slow __iomem *uccp = qe_port->uccp; | ||
575 | u16 events; | ||
576 | |||
577 | /* Clear the interrupts */ | ||
578 | events = in_be16(&uccp->ucce); | ||
579 | out_be16(&uccp->ucce, events); | ||
580 | |||
581 | if (events & UCC_UART_UCCE_BRKE) | ||
582 | uart_handle_break(&qe_port->port); | ||
583 | |||
584 | if (events & UCC_UART_UCCE_RX) | ||
585 | qe_uart_int_rx(qe_port); | ||
586 | |||
587 | if (events & UCC_UART_UCCE_TX) | ||
588 | qe_uart_tx_pump(qe_port); | ||
589 | |||
590 | return events ? IRQ_HANDLED : IRQ_NONE; | ||
591 | } | ||
592 | |||
593 | /* Initialize buffer descriptors | ||
594 | * | ||
595 | * This function initializes all of the RX and TX buffer descriptors. | ||
596 | */ | ||
597 | static void qe_uart_initbd(struct uart_qe_port *qe_port) | ||
598 | { | ||
599 | int i; | ||
600 | void *bd_virt; | ||
601 | struct qe_bd *bdp; | ||
602 | |||
603 | /* Set the physical address of the host memory buffers in the buffer | ||
604 | * descriptors, and the virtual address for us to work with. | ||
605 | */ | ||
606 | bd_virt = qe_port->bd_virt; | ||
607 | bdp = qe_port->rx_bd_base; | ||
608 | qe_port->rx_cur = qe_port->rx_bd_base; | ||
609 | for (i = 0; i < (qe_port->rx_nrfifos - 1); i++) { | ||
610 | out_be16(&bdp->status, BD_SC_EMPTY | BD_SC_INTRPT); | ||
611 | out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port)); | ||
612 | out_be16(&bdp->length, 0); | ||
613 | bd_virt += qe_port->rx_fifosize; | ||
614 | bdp++; | ||
615 | } | ||
616 | |||
617 | /* */ | ||
618 | out_be16(&bdp->status, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT); | ||
619 | out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port)); | ||
620 | out_be16(&bdp->length, 0); | ||
621 | |||
622 | /* Set the physical address of the host memory | ||
623 | * buffers in the buffer descriptors, and the | ||
624 | * virtual address for us to work with. | ||
625 | */ | ||
626 | bd_virt = qe_port->bd_virt + | ||
627 | L1_CACHE_ALIGN(qe_port->rx_nrfifos * qe_port->rx_fifosize); | ||
628 | qe_port->tx_cur = qe_port->tx_bd_base; | ||
629 | bdp = qe_port->tx_bd_base; | ||
630 | for (i = 0; i < (qe_port->tx_nrfifos - 1); i++) { | ||
631 | out_be16(&bdp->status, BD_SC_INTRPT); | ||
632 | out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port)); | ||
633 | out_be16(&bdp->length, 0); | ||
634 | bd_virt += qe_port->tx_fifosize; | ||
635 | bdp++; | ||
636 | } | ||
637 | |||
638 | /* Loopback requires the preamble bit to be set on the first TX BD */ | ||
639 | #ifdef LOOPBACK | ||
640 | setbits16(&qe_port->tx_cur->status, BD_SC_P); | ||
641 | #endif | ||
642 | |||
643 | out_be16(&bdp->status, BD_SC_WRAP | BD_SC_INTRPT); | ||
644 | out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port)); | ||
645 | out_be16(&bdp->length, 0); | ||
646 | } | ||
647 | |||
648 | /* | ||
649 | * Initialize a UCC for UART. | ||
650 | * | ||
651 | * This function configures a given UCC to be used as a UART device. Basic | ||
652 | * UCC initialization is handled in qe_uart_request_port(). This function | ||
653 | * does all the UART-specific stuff. | ||
654 | */ | ||
655 | static void qe_uart_init_ucc(struct uart_qe_port *qe_port) | ||
656 | { | ||
657 | u32 cecr_subblock; | ||
658 | struct ucc_slow __iomem *uccp = qe_port->uccp; | ||
659 | struct ucc_uart_pram *uccup = qe_port->uccup; | ||
660 | |||
661 | unsigned int i; | ||
662 | |||
663 | /* First, disable TX and RX in the UCC */ | ||
664 | ucc_slow_disable(qe_port->us_private, COMM_DIR_RX_AND_TX); | ||
665 | |||
666 | /* Program the UCC UART parameter RAM */ | ||
667 | out_8(&uccup->common.rbmr, UCC_BMR_GBL | UCC_BMR_BO_BE); | ||
668 | out_8(&uccup->common.tbmr, UCC_BMR_GBL | UCC_BMR_BO_BE); | ||
669 | out_be16(&uccup->common.mrblr, qe_port->rx_fifosize); | ||
670 | out_be16(&uccup->maxidl, 0x10); | ||
671 | out_be16(&uccup->brkcr, 1); | ||
672 | out_be16(&uccup->parec, 0); | ||
673 | out_be16(&uccup->frmec, 0); | ||
674 | out_be16(&uccup->nosec, 0); | ||
675 | out_be16(&uccup->brkec, 0); | ||
676 | out_be16(&uccup->uaddr[0], 0); | ||
677 | out_be16(&uccup->uaddr[1], 0); | ||
678 | out_be16(&uccup->toseq, 0); | ||
679 | for (i = 0; i < 8; i++) | ||
680 | out_be16(&uccup->cchars[i], 0xC000); | ||
681 | out_be16(&uccup->rccm, 0xc0ff); | ||
682 | |||
683 | /* Configure the GUMR registers for UART */ | ||
684 | if (soft_uart) | ||
685 | /* Soft-UART requires a 1X multiplier for TX */ | ||
686 | clrsetbits_be32(&uccp->gumr_l, | ||
687 | UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | | ||
688 | UCC_SLOW_GUMR_L_RDCR_MASK, | ||
689 | UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_1 | | ||
690 | UCC_SLOW_GUMR_L_RDCR_16); | ||
691 | else | ||
692 | clrsetbits_be32(&uccp->gumr_l, | ||
693 | UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | | ||
694 | UCC_SLOW_GUMR_L_RDCR_MASK, | ||
695 | UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_16 | | ||
696 | UCC_SLOW_GUMR_L_RDCR_16); | ||
697 | |||
698 | clrsetbits_be32(&uccp->gumr_h, UCC_SLOW_GUMR_H_RFW, | ||
699 | UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX); | ||
700 | |||
701 | #ifdef LOOPBACK | ||
702 | clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK, | ||
703 | UCC_SLOW_GUMR_L_DIAG_LOOP); | ||
704 | clrsetbits_be32(&uccp->gumr_h, | ||
705 | UCC_SLOW_GUMR_H_CTSP | UCC_SLOW_GUMR_H_RSYN, | ||
706 | UCC_SLOW_GUMR_H_CDS); | ||
707 | #endif | ||
708 | |||
709 | /* Enable rx interrupts and clear all pending events. */ | ||
710 | out_be16(&uccp->uccm, 0); | ||
711 | out_be16(&uccp->ucce, 0xffff); | ||
712 | out_be16(&uccp->udsr, 0x7e7e); | ||
713 | |||
714 | /* Initialize UPSMR */ | ||
715 | out_be16(&uccp->upsmr, 0); | ||
716 | |||
717 | if (soft_uart) { | ||
718 | out_be16(&uccup->supsmr, 0x30); | ||
719 | out_be16(&uccup->res92, 0); | ||
720 | out_be32(&uccup->rx_state, 0); | ||
721 | out_be32(&uccup->rx_cnt, 0); | ||
722 | out_8(&uccup->rx_bitmark, 0); | ||
723 | out_8(&uccup->rx_length, 10); | ||
724 | out_be32(&uccup->dump_ptr, 0x4000); | ||
725 | out_8(&uccup->rx_temp_dlst_qe, 0); | ||
726 | out_be32(&uccup->rx_frame_rem, 0); | ||
727 | out_8(&uccup->rx_frame_rem_size, 0); | ||
728 | /* Soft-UART requires TX to be 1X */ | ||
729 | out_8(&uccup->tx_mode, | ||
730 | UCC_UART_TX_STATE_UART | UCC_UART_TX_STATE_X1); | ||
731 | out_be16(&uccup->tx_state, 0); | ||
732 | out_8(&uccup->resD4, 0); | ||
733 | out_be16(&uccup->resD5, 0); | ||
734 | |||
735 | /* Set UART mode. | ||
736 | * Enable receive and transmit. | ||
737 | */ | ||
738 | |||
739 | /* From the microcode errata: | ||
740 | * 1.GUMR_L register, set mode=0010 (QMC). | ||
741 | * 2.Set GUMR_H[17] bit. (UART/AHDLC mode). | ||
742 | * 3.Set GUMR_H[19:20] (Transparent mode) | ||
743 | * 4.Clear GUMR_H[26] (RFW) | ||
744 | * ... | ||
745 | * 6.Receiver must use 16x over sampling | ||
746 | */ | ||
747 | clrsetbits_be32(&uccp->gumr_l, | ||
748 | UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | | ||
749 | UCC_SLOW_GUMR_L_RDCR_MASK, | ||
750 | UCC_SLOW_GUMR_L_MODE_QMC | UCC_SLOW_GUMR_L_TDCR_16 | | ||
751 | UCC_SLOW_GUMR_L_RDCR_16); | ||
752 | |||
753 | clrsetbits_be32(&uccp->gumr_h, | ||
754 | UCC_SLOW_GUMR_H_RFW | UCC_SLOW_GUMR_H_RSYN, | ||
755 | UCC_SLOW_GUMR_H_SUART | UCC_SLOW_GUMR_H_TRX | | ||
756 | UCC_SLOW_GUMR_H_TTX | UCC_SLOW_GUMR_H_TFL); | ||
757 | |||
758 | #ifdef LOOPBACK | ||
759 | clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK, | ||
760 | UCC_SLOW_GUMR_L_DIAG_LOOP); | ||
761 | clrbits32(&uccp->gumr_h, UCC_SLOW_GUMR_H_CTSP | | ||
762 | UCC_SLOW_GUMR_H_CDS); | ||
763 | #endif | ||
764 | |||
765 | cecr_subblock = ucc_slow_get_qe_cr_subblock(qe_port->ucc_num); | ||
766 | qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock, | ||
767 | QE_CR_PROTOCOL_UNSPECIFIED, 0); | ||
768 | } | ||
769 | } | ||
770 | |||
771 | /* | ||
772 | * Initialize the port. | ||
773 | */ | ||
774 | static int qe_uart_startup(struct uart_port *port) | ||
775 | { | ||
776 | struct uart_qe_port *qe_port = | ||
777 | container_of(port, struct uart_qe_port, port); | ||
778 | int ret; | ||
779 | |||
780 | /* | ||
781 | * If we're using Soft-UART mode, then we need to make sure the | ||
782 | * firmware has been uploaded first. | ||
783 | */ | ||
784 | if (soft_uart && !firmware_loaded) { | ||
785 | dev_err(port->dev, "Soft-UART firmware not uploaded\n"); | ||
786 | return -ENODEV; | ||
787 | } | ||
788 | |||
789 | qe_uart_initbd(qe_port); | ||
790 | qe_uart_init_ucc(qe_port); | ||
791 | |||
792 | /* Install interrupt handler. */ | ||
793 | ret = request_irq(port->irq, qe_uart_int, IRQF_SHARED, "ucc-uart", | ||
794 | qe_port); | ||
795 | if (ret) { | ||
796 | dev_err(port->dev, "could not claim IRQ %u\n", port->irq); | ||
797 | return ret; | ||
798 | } | ||
799 | |||
800 | /* Startup rx-int */ | ||
801 | setbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX); | ||
802 | ucc_slow_enable(qe_port->us_private, COMM_DIR_RX_AND_TX); | ||
803 | |||
804 | return 0; | ||
805 | } | ||
806 | |||
807 | /* | ||
808 | * Shutdown the port. | ||
809 | */ | ||
810 | static void qe_uart_shutdown(struct uart_port *port) | ||
811 | { | ||
812 | struct uart_qe_port *qe_port = | ||
813 | container_of(port, struct uart_qe_port, port); | ||
814 | struct ucc_slow __iomem *uccp = qe_port->uccp; | ||
815 | unsigned int timeout = 20; | ||
816 | |||
817 | /* Disable RX and TX */ | ||
818 | |||
819 | /* Wait for all the BDs marked sent */ | ||
820 | while (!qe_uart_tx_empty(port)) { | ||
821 | if (!--timeout) { | ||
822 | dev_warn(port->dev, "shutdown timeout\n"); | ||
823 | break; | ||
824 | } | ||
825 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
826 | schedule_timeout(2); | ||
827 | } | ||
828 | |||
829 | if (qe_port->wait_closing) { | ||
830 | /* Wait a bit longer */ | ||
831 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
832 | schedule_timeout(qe_port->wait_closing); | ||
833 | } | ||
834 | |||
835 | /* Stop uarts */ | ||
836 | ucc_slow_disable(qe_port->us_private, COMM_DIR_RX_AND_TX); | ||
837 | clrbits16(&uccp->uccm, UCC_UART_UCCE_TX | UCC_UART_UCCE_RX); | ||
838 | |||
839 | /* Shut them really down and reinit buffer descriptors */ | ||
840 | ucc_slow_graceful_stop_tx(qe_port->us_private); | ||
841 | qe_uart_initbd(qe_port); | ||
842 | |||
843 | free_irq(port->irq, qe_port); | ||
844 | } | ||
845 | |||
846 | /* | ||
847 | * Set the serial port parameters. | ||
848 | */ | ||
849 | static void qe_uart_set_termios(struct uart_port *port, | ||
850 | struct ktermios *termios, struct ktermios *old) | ||
851 | { | ||
852 | struct uart_qe_port *qe_port = | ||
853 | container_of(port, struct uart_qe_port, port); | ||
854 | struct ucc_slow __iomem *uccp = qe_port->uccp; | ||
855 | unsigned int baud; | ||
856 | unsigned long flags; | ||
857 | u16 upsmr = in_be16(&uccp->upsmr); | ||
858 | struct ucc_uart_pram __iomem *uccup = qe_port->uccup; | ||
859 | u16 supsmr = in_be16(&uccup->supsmr); | ||
860 | u8 char_length = 2; /* 1 + CL + PEN + 1 + SL */ | ||
861 | |||
862 | /* Character length programmed into the mode register is the | ||
863 | * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, | ||
864 | * 1 or 2 stop bits, minus 1. | ||
865 | * The value 'bits' counts this for us. | ||
866 | */ | ||
867 | |||
868 | /* byte size */ | ||
869 | upsmr &= UCC_UART_UPSMR_CL_MASK; | ||
870 | supsmr &= UCC_UART_SUPSMR_CL_MASK; | ||
871 | |||
872 | switch (termios->c_cflag & CSIZE) { | ||
873 | case CS5: | ||
874 | upsmr |= UCC_UART_UPSMR_CL_5; | ||
875 | supsmr |= UCC_UART_SUPSMR_CL_5; | ||
876 | char_length += 5; | ||
877 | break; | ||
878 | case CS6: | ||
879 | upsmr |= UCC_UART_UPSMR_CL_6; | ||
880 | supsmr |= UCC_UART_SUPSMR_CL_6; | ||
881 | char_length += 6; | ||
882 | break; | ||
883 | case CS7: | ||
884 | upsmr |= UCC_UART_UPSMR_CL_7; | ||
885 | supsmr |= UCC_UART_SUPSMR_CL_7; | ||
886 | char_length += 7; | ||
887 | break; | ||
888 | default: /* case CS8 */ | ||
889 | upsmr |= UCC_UART_UPSMR_CL_8; | ||
890 | supsmr |= UCC_UART_SUPSMR_CL_8; | ||
891 | char_length += 8; | ||
892 | break; | ||
893 | } | ||
894 | |||
895 | /* If CSTOPB is set, we want two stop bits */ | ||
896 | if (termios->c_cflag & CSTOPB) { | ||
897 | upsmr |= UCC_UART_UPSMR_SL; | ||
898 | supsmr |= UCC_UART_SUPSMR_SL; | ||
899 | char_length++; /* + SL */ | ||
900 | } | ||
901 | |||
902 | if (termios->c_cflag & PARENB) { | ||
903 | upsmr |= UCC_UART_UPSMR_PEN; | ||
904 | supsmr |= UCC_UART_SUPSMR_PEN; | ||
905 | char_length++; /* + PEN */ | ||
906 | |||
907 | if (!(termios->c_cflag & PARODD)) { | ||
908 | upsmr &= ~(UCC_UART_UPSMR_RPM_MASK | | ||
909 | UCC_UART_UPSMR_TPM_MASK); | ||
910 | upsmr |= UCC_UART_UPSMR_RPM_EVEN | | ||
911 | UCC_UART_UPSMR_TPM_EVEN; | ||
912 | supsmr &= ~(UCC_UART_SUPSMR_RPM_MASK | | ||
913 | UCC_UART_SUPSMR_TPM_MASK); | ||
914 | supsmr |= UCC_UART_SUPSMR_RPM_EVEN | | ||
915 | UCC_UART_SUPSMR_TPM_EVEN; | ||
916 | } | ||
917 | } | ||
918 | |||
919 | /* | ||
920 | * Set up parity check flag | ||
921 | */ | ||
922 | port->read_status_mask = BD_SC_EMPTY | BD_SC_OV; | ||
923 | if (termios->c_iflag & INPCK) | ||
924 | port->read_status_mask |= BD_SC_FR | BD_SC_PR; | ||
925 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
926 | port->read_status_mask |= BD_SC_BR; | ||
927 | |||
928 | /* | ||
929 | * Characters to ignore | ||
930 | */ | ||
931 | port->ignore_status_mask = 0; | ||
932 | if (termios->c_iflag & IGNPAR) | ||
933 | port->ignore_status_mask |= BD_SC_PR | BD_SC_FR; | ||
934 | if (termios->c_iflag & IGNBRK) { | ||
935 | port->ignore_status_mask |= BD_SC_BR; | ||
936 | /* | ||
937 | * If we're ignore parity and break indicators, ignore | ||
938 | * overruns too. (For real raw support). | ||
939 | */ | ||
940 | if (termios->c_iflag & IGNPAR) | ||
941 | port->ignore_status_mask |= BD_SC_OV; | ||
942 | } | ||
943 | /* | ||
944 | * !!! ignore all characters if CREAD is not set | ||
945 | */ | ||
946 | if ((termios->c_cflag & CREAD) == 0) | ||
947 | port->read_status_mask &= ~BD_SC_EMPTY; | ||
948 | |||
949 | baud = uart_get_baud_rate(port, termios, old, 0, 115200); | ||
950 | |||
951 | /* Do we really need a spinlock here? */ | ||
952 | spin_lock_irqsave(&port->lock, flags); | ||
953 | |||
954 | out_be16(&uccp->upsmr, upsmr); | ||
955 | if (soft_uart) { | ||
956 | out_be16(&uccup->supsmr, supsmr); | ||
957 | out_8(&uccup->rx_length, char_length); | ||
958 | |||
959 | /* Soft-UART requires a 1X multiplier for TX */ | ||
960 | qe_setbrg(qe_port->us_info.rx_clock, baud, 16); | ||
961 | qe_setbrg(qe_port->us_info.tx_clock, baud, 1); | ||
962 | } else { | ||
963 | qe_setbrg(qe_port->us_info.rx_clock, baud, 16); | ||
964 | qe_setbrg(qe_port->us_info.tx_clock, baud, 16); | ||
965 | } | ||
966 | |||
967 | spin_unlock_irqrestore(&port->lock, flags); | ||
968 | } | ||
969 | |||
970 | /* | ||
971 | * Return a pointer to a string that describes what kind of port this is. | ||
972 | */ | ||
973 | static const char *qe_uart_type(struct uart_port *port) | ||
974 | { | ||
975 | return "QE"; | ||
976 | } | ||
977 | |||
978 | /* | ||
979 | * Allocate any memory and I/O resources required by the port. | ||
980 | */ | ||
981 | static int qe_uart_request_port(struct uart_port *port) | ||
982 | { | ||
983 | int ret; | ||
984 | struct uart_qe_port *qe_port = | ||
985 | container_of(port, struct uart_qe_port, port); | ||
986 | struct ucc_slow_info *us_info = &qe_port->us_info; | ||
987 | struct ucc_slow_private *uccs; | ||
988 | unsigned int rx_size, tx_size; | ||
989 | void *bd_virt; | ||
990 | dma_addr_t bd_dma_addr = 0; | ||
991 | |||
992 | ret = ucc_slow_init(us_info, &uccs); | ||
993 | if (ret) { | ||
994 | dev_err(port->dev, "could not initialize UCC%u\n", | ||
995 | qe_port->ucc_num); | ||
996 | return ret; | ||
997 | } | ||
998 | |||
999 | qe_port->us_private = uccs; | ||
1000 | qe_port->uccp = uccs->us_regs; | ||
1001 | qe_port->uccup = (struct ucc_uart_pram *) uccs->us_pram; | ||
1002 | qe_port->rx_bd_base = uccs->rx_bd; | ||
1003 | qe_port->tx_bd_base = uccs->tx_bd; | ||
1004 | |||
1005 | /* | ||
1006 | * Allocate the transmit and receive data buffers. | ||
1007 | */ | ||
1008 | |||
1009 | rx_size = L1_CACHE_ALIGN(qe_port->rx_nrfifos * qe_port->rx_fifosize); | ||
1010 | tx_size = L1_CACHE_ALIGN(qe_port->tx_nrfifos * qe_port->tx_fifosize); | ||
1011 | |||
1012 | bd_virt = dma_alloc_coherent(NULL, rx_size + tx_size, &bd_dma_addr, | ||
1013 | GFP_KERNEL); | ||
1014 | if (!bd_virt) { | ||
1015 | dev_err(port->dev, "could not allocate buffer descriptors\n"); | ||
1016 | return -ENOMEM; | ||
1017 | } | ||
1018 | |||
1019 | qe_port->bd_virt = bd_virt; | ||
1020 | qe_port->bd_dma_addr = bd_dma_addr; | ||
1021 | qe_port->bd_size = rx_size + tx_size; | ||
1022 | |||
1023 | qe_port->rx_buf = bd_virt; | ||
1024 | qe_port->tx_buf = qe_port->rx_buf + rx_size; | ||
1025 | |||
1026 | return 0; | ||
1027 | } | ||
1028 | |||
1029 | /* | ||
1030 | * Configure the port. | ||
1031 | * | ||
1032 | * We say we're a CPM-type port because that's mostly true. Once the device | ||
1033 | * is configured, this driver operates almost identically to the CPM serial | ||
1034 | * driver. | ||
1035 | */ | ||
1036 | static void qe_uart_config_port(struct uart_port *port, int flags) | ||
1037 | { | ||
1038 | if (flags & UART_CONFIG_TYPE) { | ||
1039 | port->type = PORT_CPM; | ||
1040 | qe_uart_request_port(port); | ||
1041 | } | ||
1042 | } | ||
1043 | |||
1044 | /* | ||
1045 | * Release any memory and I/O resources that were allocated in | ||
1046 | * qe_uart_request_port(). | ||
1047 | */ | ||
1048 | static void qe_uart_release_port(struct uart_port *port) | ||
1049 | { | ||
1050 | struct uart_qe_port *qe_port = | ||
1051 | container_of(port, struct uart_qe_port, port); | ||
1052 | struct ucc_slow_private *uccs = qe_port->us_private; | ||
1053 | |||
1054 | dma_free_coherent(NULL, qe_port->bd_size, qe_port->bd_virt, | ||
1055 | qe_port->bd_dma_addr); | ||
1056 | |||
1057 | ucc_slow_free(uccs); | ||
1058 | } | ||
1059 | |||
1060 | /* | ||
1061 | * Verify that the data in serial_struct is suitable for this device. | ||
1062 | */ | ||
1063 | static int qe_uart_verify_port(struct uart_port *port, | ||
1064 | struct serial_struct *ser) | ||
1065 | { | ||
1066 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) | ||
1067 | return -EINVAL; | ||
1068 | |||
1069 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | ||
1070 | return -EINVAL; | ||
1071 | |||
1072 | if (ser->baud_base < 9600) | ||
1073 | return -EINVAL; | ||
1074 | |||
1075 | return 0; | ||
1076 | } | ||
1077 | /* UART operations | ||
1078 | * | ||
1079 | * Details on these functions can be found in Documentation/serial/driver | ||
1080 | */ | ||
1081 | static struct uart_ops qe_uart_pops = { | ||
1082 | .tx_empty = qe_uart_tx_empty, | ||
1083 | .set_mctrl = qe_uart_set_mctrl, | ||
1084 | .get_mctrl = qe_uart_get_mctrl, | ||
1085 | .stop_tx = qe_uart_stop_tx, | ||
1086 | .start_tx = qe_uart_start_tx, | ||
1087 | .stop_rx = qe_uart_stop_rx, | ||
1088 | .enable_ms = qe_uart_enable_ms, | ||
1089 | .break_ctl = qe_uart_break_ctl, | ||
1090 | .startup = qe_uart_startup, | ||
1091 | .shutdown = qe_uart_shutdown, | ||
1092 | .set_termios = qe_uart_set_termios, | ||
1093 | .type = qe_uart_type, | ||
1094 | .release_port = qe_uart_release_port, | ||
1095 | .request_port = qe_uart_request_port, | ||
1096 | .config_port = qe_uart_config_port, | ||
1097 | .verify_port = qe_uart_verify_port, | ||
1098 | }; | ||
1099 | |||
1100 | /* | ||
1101 | * Obtain the SOC model number and revision level | ||
1102 | * | ||
1103 | * This function parses the device tree to obtain the SOC model. It then | ||
1104 | * reads the SVR register to the revision. | ||
1105 | * | ||
1106 | * The device tree stores the SOC model two different ways. | ||
1107 | * | ||
1108 | * The new way is: | ||
1109 | * | ||
1110 | * cpu@0 { | ||
1111 | * compatible = "PowerPC,8323"; | ||
1112 | * device_type = "cpu"; | ||
1113 | * ... | ||
1114 | * | ||
1115 | * | ||
1116 | * The old way is: | ||
1117 | * PowerPC,8323@0 { | ||
1118 | * device_type = "cpu"; | ||
1119 | * ... | ||
1120 | * | ||
1121 | * This code first checks the new way, and then the old way. | ||
1122 | */ | ||
1123 | static unsigned int soc_info(unsigned int *rev_h, unsigned int *rev_l) | ||
1124 | { | ||
1125 | struct device_node *np; | ||
1126 | const char *soc_string; | ||
1127 | unsigned int svr; | ||
1128 | unsigned int soc; | ||
1129 | |||
1130 | /* Find the CPU node */ | ||
1131 | np = of_find_node_by_type(NULL, "cpu"); | ||
1132 | if (!np) | ||
1133 | return 0; | ||
1134 | /* Find the compatible property */ | ||
1135 | soc_string = of_get_property(np, "compatible", NULL); | ||
1136 | if (!soc_string) | ||
1137 | /* No compatible property, so try the name. */ | ||
1138 | soc_string = np->name; | ||
1139 | |||
1140 | /* Extract the SOC number from the "PowerPC," string */ | ||
1141 | if ((sscanf(soc_string, "PowerPC,%u", &soc) != 1) || !soc) | ||
1142 | return 0; | ||
1143 | |||
1144 | /* Get the revision from the SVR */ | ||
1145 | svr = mfspr(SPRN_SVR); | ||
1146 | *rev_h = (svr >> 4) & 0xf; | ||
1147 | *rev_l = svr & 0xf; | ||
1148 | |||
1149 | return soc; | ||
1150 | } | ||
1151 | |||
1152 | /* | ||
1153 | * requst_firmware_nowait() callback function | ||
1154 | * | ||
1155 | * This function is called by the kernel when a firmware is made available, | ||
1156 | * or if it times out waiting for the firmware. | ||
1157 | */ | ||
1158 | static void uart_firmware_cont(const struct firmware *fw, void *context) | ||
1159 | { | ||
1160 | struct qe_firmware *firmware; | ||
1161 | struct device *dev = context; | ||
1162 | int ret; | ||
1163 | |||
1164 | if (!fw) { | ||
1165 | dev_err(dev, "firmware not found\n"); | ||
1166 | return; | ||
1167 | } | ||
1168 | |||
1169 | firmware = (struct qe_firmware *) fw->data; | ||
1170 | |||
1171 | if (firmware->header.length != fw->size) { | ||
1172 | dev_err(dev, "invalid firmware\n"); | ||
1173 | return; | ||
1174 | } | ||
1175 | |||
1176 | ret = qe_upload_firmware(firmware); | ||
1177 | if (ret) { | ||
1178 | dev_err(dev, "could not load firmware\n"); | ||
1179 | return; | ||
1180 | } | ||
1181 | |||
1182 | firmware_loaded = 1; | ||
1183 | } | ||
1184 | |||
1185 | static int ucc_uart_probe(struct of_device *ofdev, | ||
1186 | const struct of_device_id *match) | ||
1187 | { | ||
1188 | struct device_node *np = ofdev->node; | ||
1189 | const unsigned int *iprop; /* Integer OF properties */ | ||
1190 | const char *sprop; /* String OF properties */ | ||
1191 | struct uart_qe_port *qe_port = NULL; | ||
1192 | struct resource res; | ||
1193 | int ret; | ||
1194 | |||
1195 | /* | ||
1196 | * Determine if we need Soft-UART mode | ||
1197 | */ | ||
1198 | if (of_find_property(np, "soft-uart", NULL)) { | ||
1199 | dev_dbg(&ofdev->dev, "using Soft-UART mode\n"); | ||
1200 | soft_uart = 1; | ||
1201 | } | ||
1202 | |||
1203 | /* | ||
1204 | * If we are using Soft-UART, determine if we need to upload the | ||
1205 | * firmware, too. | ||
1206 | */ | ||
1207 | if (soft_uart) { | ||
1208 | struct qe_firmware_info *qe_fw_info; | ||
1209 | |||
1210 | qe_fw_info = qe_get_firmware_info(); | ||
1211 | |||
1212 | /* Check if the firmware has been uploaded. */ | ||
1213 | if (qe_fw_info && strstr(qe_fw_info->id, "Soft-UART")) { | ||
1214 | firmware_loaded = 1; | ||
1215 | } else { | ||
1216 | char filename[32]; | ||
1217 | unsigned int soc; | ||
1218 | unsigned int rev_h; | ||
1219 | unsigned int rev_l; | ||
1220 | |||
1221 | soc = soc_info(&rev_h, &rev_l); | ||
1222 | if (!soc) { | ||
1223 | dev_err(&ofdev->dev, "unknown CPU model\n"); | ||
1224 | return -ENXIO; | ||
1225 | } | ||
1226 | sprintf(filename, "fsl_qe_ucode_uart_%u_%u%u.bin", | ||
1227 | soc, rev_h, rev_l); | ||
1228 | |||
1229 | dev_info(&ofdev->dev, "waiting for firmware %s\n", | ||
1230 | filename); | ||
1231 | |||
1232 | /* | ||
1233 | * We call request_firmware_nowait instead of | ||
1234 | * request_firmware so that the driver can load and | ||
1235 | * initialize the ports without holding up the rest of | ||
1236 | * the kernel. If hotplug support is enabled in the | ||
1237 | * kernel, then we use it. | ||
1238 | */ | ||
1239 | ret = request_firmware_nowait(THIS_MODULE, | ||
1240 | FW_ACTION_HOTPLUG, filename, &ofdev->dev, | ||
1241 | &ofdev->dev, uart_firmware_cont); | ||
1242 | if (ret) { | ||
1243 | dev_err(&ofdev->dev, | ||
1244 | "could not load firmware %s\n", | ||
1245 | filename); | ||
1246 | return ret; | ||
1247 | } | ||
1248 | } | ||
1249 | } | ||
1250 | |||
1251 | qe_port = kzalloc(sizeof(struct uart_qe_port), GFP_KERNEL); | ||
1252 | if (!qe_port) { | ||
1253 | dev_err(&ofdev->dev, "can't allocate QE port structure\n"); | ||
1254 | return -ENOMEM; | ||
1255 | } | ||
1256 | |||
1257 | /* Search for IRQ and mapbase */ | ||
1258 | ret = of_address_to_resource(np, 0, &res); | ||
1259 | if (ret) { | ||
1260 | dev_err(&ofdev->dev, "missing 'reg' property in device tree\n"); | ||
1261 | kfree(qe_port); | ||
1262 | return ret; | ||
1263 | } | ||
1264 | if (!res.start) { | ||
1265 | dev_err(&ofdev->dev, "invalid 'reg' property in device tree\n"); | ||
1266 | kfree(qe_port); | ||
1267 | return -EINVAL; | ||
1268 | } | ||
1269 | qe_port->port.mapbase = res.start; | ||
1270 | |||
1271 | /* Get the UCC number (device ID) */ | ||
1272 | /* UCCs are numbered 1-7 */ | ||
1273 | iprop = of_get_property(np, "device-id", NULL); | ||
1274 | if (!iprop || (*iprop < 1) || (*iprop > UCC_MAX_NUM)) { | ||
1275 | dev_err(&ofdev->dev, | ||
1276 | "missing or invalid UCC specified in device tree\n"); | ||
1277 | kfree(qe_port); | ||
1278 | return -ENODEV; | ||
1279 | } | ||
1280 | qe_port->ucc_num = *iprop - 1; | ||
1281 | |||
1282 | /* | ||
1283 | * In the future, we should not require the BRG to be specified in the | ||
1284 | * device tree. If no clock-source is specified, then just pick a BRG | ||
1285 | * to use. This requires a new QE library function that manages BRG | ||
1286 | * assignments. | ||
1287 | */ | ||
1288 | |||
1289 | sprop = of_get_property(np, "rx-clock-name", NULL); | ||
1290 | if (!sprop) { | ||
1291 | dev_err(&ofdev->dev, "missing rx-clock-name in device tree\n"); | ||
1292 | kfree(qe_port); | ||
1293 | return -ENODEV; | ||
1294 | } | ||
1295 | |||
1296 | qe_port->us_info.rx_clock = qe_clock_source(sprop); | ||
1297 | if ((qe_port->us_info.rx_clock < QE_BRG1) || | ||
1298 | (qe_port->us_info.rx_clock > QE_BRG16)) { | ||
1299 | dev_err(&ofdev->dev, "rx-clock-name must be a BRG for UART\n"); | ||
1300 | kfree(qe_port); | ||
1301 | return -ENODEV; | ||
1302 | } | ||
1303 | |||
1304 | #ifdef LOOPBACK | ||
1305 | /* In internal loopback mode, TX and RX must use the same clock */ | ||
1306 | qe_port->us_info.tx_clock = qe_port->us_info.rx_clock; | ||
1307 | #else | ||
1308 | sprop = of_get_property(np, "tx-clock-name", NULL); | ||
1309 | if (!sprop) { | ||
1310 | dev_err(&ofdev->dev, "missing tx-clock-name in device tree\n"); | ||
1311 | kfree(qe_port); | ||
1312 | return -ENODEV; | ||
1313 | } | ||
1314 | qe_port->us_info.tx_clock = qe_clock_source(sprop); | ||
1315 | #endif | ||
1316 | if ((qe_port->us_info.tx_clock < QE_BRG1) || | ||
1317 | (qe_port->us_info.tx_clock > QE_BRG16)) { | ||
1318 | dev_err(&ofdev->dev, "tx-clock-name must be a BRG for UART\n"); | ||
1319 | kfree(qe_port); | ||
1320 | return -ENODEV; | ||
1321 | } | ||
1322 | |||
1323 | /* Get the port number, numbered 0-3 */ | ||
1324 | iprop = of_get_property(np, "port-number", NULL); | ||
1325 | if (!iprop) { | ||
1326 | dev_err(&ofdev->dev, "missing port-number in device tree\n"); | ||
1327 | kfree(qe_port); | ||
1328 | return -EINVAL; | ||
1329 | } | ||
1330 | qe_port->port.line = *iprop; | ||
1331 | if (qe_port->port.line >= UCC_MAX_UART) { | ||
1332 | dev_err(&ofdev->dev, "port-number must be 0-%u\n", | ||
1333 | UCC_MAX_UART - 1); | ||
1334 | kfree(qe_port); | ||
1335 | return -EINVAL; | ||
1336 | } | ||
1337 | |||
1338 | qe_port->port.irq = irq_of_parse_and_map(np, 0); | ||
1339 | if (qe_port->port.irq == NO_IRQ) { | ||
1340 | dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n", | ||
1341 | qe_port->ucc_num + 1); | ||
1342 | kfree(qe_port); | ||
1343 | return -EINVAL; | ||
1344 | } | ||
1345 | |||
1346 | /* | ||
1347 | * Newer device trees have an "fsl,qe" compatible property for the QE | ||
1348 | * node, but we still need to support older device trees. | ||
1349 | */ | ||
1350 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); | ||
1351 | if (!np) { | ||
1352 | np = of_find_node_by_type(NULL, "qe"); | ||
1353 | if (!np) { | ||
1354 | dev_err(&ofdev->dev, "could not find 'qe' node\n"); | ||
1355 | kfree(qe_port); | ||
1356 | return -EINVAL; | ||
1357 | } | ||
1358 | } | ||
1359 | |||
1360 | iprop = of_get_property(np, "brg-frequency", NULL); | ||
1361 | if (!iprop) { | ||
1362 | dev_err(&ofdev->dev, | ||
1363 | "missing brg-frequency in device tree\n"); | ||
1364 | kfree(qe_port); | ||
1365 | return -EINVAL; | ||
1366 | } | ||
1367 | |||
1368 | if (*iprop) | ||
1369 | qe_port->port.uartclk = *iprop; | ||
1370 | else { | ||
1371 | /* | ||
1372 | * Older versions of U-Boot do not initialize the brg-frequency | ||
1373 | * property, so in this case we assume the BRG frequency is | ||
1374 | * half the QE bus frequency. | ||
1375 | */ | ||
1376 | iprop = of_get_property(np, "bus-frequency", NULL); | ||
1377 | if (!iprop) { | ||
1378 | dev_err(&ofdev->dev, | ||
1379 | "missing QE bus-frequency in device tree\n"); | ||
1380 | kfree(qe_port); | ||
1381 | return -EINVAL; | ||
1382 | } | ||
1383 | if (*iprop) | ||
1384 | qe_port->port.uartclk = *iprop / 2; | ||
1385 | else { | ||
1386 | dev_err(&ofdev->dev, | ||
1387 | "invalid QE bus-frequency in device tree\n"); | ||
1388 | kfree(qe_port); | ||
1389 | return -EINVAL; | ||
1390 | } | ||
1391 | } | ||
1392 | |||
1393 | spin_lock_init(&qe_port->port.lock); | ||
1394 | qe_port->np = np; | ||
1395 | qe_port->port.dev = &ofdev->dev; | ||
1396 | qe_port->port.ops = &qe_uart_pops; | ||
1397 | qe_port->port.iotype = UPIO_MEM; | ||
1398 | |||
1399 | qe_port->tx_nrfifos = TX_NUM_FIFO; | ||
1400 | qe_port->tx_fifosize = TX_BUF_SIZE; | ||
1401 | qe_port->rx_nrfifos = RX_NUM_FIFO; | ||
1402 | qe_port->rx_fifosize = RX_BUF_SIZE; | ||
1403 | |||
1404 | qe_port->wait_closing = UCC_WAIT_CLOSING; | ||
1405 | qe_port->port.fifosize = 512; | ||
1406 | qe_port->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP; | ||
1407 | |||
1408 | qe_port->us_info.ucc_num = qe_port->ucc_num; | ||
1409 | qe_port->us_info.regs = (phys_addr_t) res.start; | ||
1410 | qe_port->us_info.irq = qe_port->port.irq; | ||
1411 | |||
1412 | qe_port->us_info.rx_bd_ring_len = qe_port->rx_nrfifos; | ||
1413 | qe_port->us_info.tx_bd_ring_len = qe_port->tx_nrfifos; | ||
1414 | |||
1415 | /* Make sure ucc_slow_init() initializes both TX and RX */ | ||
1416 | qe_port->us_info.init_tx = 1; | ||
1417 | qe_port->us_info.init_rx = 1; | ||
1418 | |||
1419 | /* Add the port to the uart sub-system. This will cause | ||
1420 | * qe_uart_config_port() to be called, so the us_info structure must | ||
1421 | * be initialized. | ||
1422 | */ | ||
1423 | ret = uart_add_one_port(&ucc_uart_driver, &qe_port->port); | ||
1424 | if (ret) { | ||
1425 | dev_err(&ofdev->dev, "could not add /dev/ttyQE%u\n", | ||
1426 | qe_port->port.line); | ||
1427 | kfree(qe_port); | ||
1428 | return ret; | ||
1429 | } | ||
1430 | |||
1431 | dev_set_drvdata(&ofdev->dev, qe_port); | ||
1432 | |||
1433 | dev_info(&ofdev->dev, "UCC%u assigned to /dev/ttyQE%u\n", | ||
1434 | qe_port->ucc_num + 1, qe_port->port.line); | ||
1435 | |||
1436 | /* Display the mknod command for this device */ | ||
1437 | dev_dbg(&ofdev->dev, "mknod command is 'mknod /dev/ttyQE%u c %u %u'\n", | ||
1438 | qe_port->port.line, SERIAL_QE_MAJOR, | ||
1439 | SERIAL_QE_MINOR + qe_port->port.line); | ||
1440 | |||
1441 | return 0; | ||
1442 | } | ||
1443 | |||
1444 | static int ucc_uart_remove(struct of_device *ofdev) | ||
1445 | { | ||
1446 | struct uart_qe_port *qe_port = dev_get_drvdata(&ofdev->dev); | ||
1447 | |||
1448 | dev_info(&ofdev->dev, "removing /dev/ttyQE%u\n", qe_port->port.line); | ||
1449 | |||
1450 | uart_remove_one_port(&ucc_uart_driver, &qe_port->port); | ||
1451 | |||
1452 | dev_set_drvdata(&ofdev->dev, NULL); | ||
1453 | kfree(qe_port); | ||
1454 | |||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1458 | static struct of_device_id ucc_uart_match[] = { | ||
1459 | { | ||
1460 | .type = "serial", | ||
1461 | .compatible = "ucc_uart", | ||
1462 | }, | ||
1463 | {}, | ||
1464 | }; | ||
1465 | MODULE_DEVICE_TABLE(of, ucc_uart_match); | ||
1466 | |||
1467 | static struct of_platform_driver ucc_uart_of_driver = { | ||
1468 | .owner = THIS_MODULE, | ||
1469 | .name = "ucc_uart", | ||
1470 | .match_table = ucc_uart_match, | ||
1471 | .probe = ucc_uart_probe, | ||
1472 | .remove = ucc_uart_remove, | ||
1473 | }; | ||
1474 | |||
1475 | static int __init ucc_uart_init(void) | ||
1476 | { | ||
1477 | int ret; | ||
1478 | |||
1479 | printk(KERN_INFO "Freescale QUICC Engine UART device driver\n"); | ||
1480 | #ifdef LOOPBACK | ||
1481 | printk(KERN_INFO "ucc-uart: Using loopback mode\n"); | ||
1482 | #endif | ||
1483 | |||
1484 | ret = uart_register_driver(&ucc_uart_driver); | ||
1485 | if (ret) { | ||
1486 | printk(KERN_ERR "ucc-uart: could not register UART driver\n"); | ||
1487 | return ret; | ||
1488 | } | ||
1489 | |||
1490 | ret = of_register_platform_driver(&ucc_uart_of_driver); | ||
1491 | if (ret) | ||
1492 | printk(KERN_ERR | ||
1493 | "ucc-uart: could not register platform driver\n"); | ||
1494 | |||
1495 | return ret; | ||
1496 | } | ||
1497 | |||
1498 | static void __exit ucc_uart_exit(void) | ||
1499 | { | ||
1500 | printk(KERN_INFO | ||
1501 | "Freescale QUICC Engine UART device driver unloading\n"); | ||
1502 | |||
1503 | of_unregister_platform_driver(&ucc_uart_of_driver); | ||
1504 | uart_unregister_driver(&ucc_uart_driver); | ||
1505 | } | ||
1506 | |||
1507 | module_init(ucc_uart_init); | ||
1508 | module_exit(ucc_uart_exit); | ||
1509 | |||
1510 | MODULE_DESCRIPTION("Freescale QUICC Engine (QE) UART"); | ||
1511 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); | ||
1512 | MODULE_LICENSE("GPL v2"); | ||
1513 | MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_QE_MAJOR); | ||
1514 | |||
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 7051e6c5edc3..253ed5682a6d 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c | |||
@@ -330,75 +330,13 @@ static void mpc52xx_psc_spi_cleanup(struct spi_device *spi) | |||
330 | 330 | ||
331 | static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) | 331 | static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) |
332 | { | 332 | { |
333 | struct mpc52xx_cdm __iomem *cdm; | ||
334 | struct mpc52xx_gpio __iomem *gpio; | ||
335 | struct mpc52xx_psc __iomem *psc = mps->psc; | 333 | struct mpc52xx_psc __iomem *psc = mps->psc; |
336 | u32 ul; | ||
337 | u32 mclken_div; | 334 | u32 mclken_div; |
338 | int ret = 0; | 335 | int ret = 0; |
339 | 336 | ||
340 | #if defined(CONFIG_PPC_MERGE) | ||
341 | cdm = mpc52xx_find_and_map("mpc5200-cdm"); | ||
342 | gpio = mpc52xx_find_and_map("mpc5200-gpio"); | ||
343 | #else | ||
344 | cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE); | ||
345 | gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE); | ||
346 | #endif | ||
347 | if (!cdm || !gpio) { | ||
348 | printk(KERN_ERR "Error mapping CDM/GPIO\n"); | ||
349 | ret = -EFAULT; | ||
350 | goto unmap_regs; | ||
351 | } | ||
352 | |||
353 | /* default sysclk is 512MHz */ | 337 | /* default sysclk is 512MHz */ |
354 | mclken_div = 0x8000 | | 338 | mclken_div = (mps->sysclk ? mps->sysclk : 512000000) / MCLK; |
355 | (((mps->sysclk ? mps->sysclk : 512000000) / MCLK) & 0x1FF); | 339 | mpc52xx_set_psc_clkdiv(psc_id, mclken_div); |
356 | |||
357 | switch (psc_id) { | ||
358 | case 1: | ||
359 | ul = in_be32(&gpio->port_config); | ||
360 | ul &= 0xFFFFFFF8; | ||
361 | ul |= 0x00000006; | ||
362 | out_be32(&gpio->port_config, ul); | ||
363 | out_be16(&cdm->mclken_div_psc1, mclken_div); | ||
364 | ul = in_be32(&cdm->clk_enables); | ||
365 | ul |= 0x00000020; | ||
366 | out_be32(&cdm->clk_enables, ul); | ||
367 | break; | ||
368 | case 2: | ||
369 | ul = in_be32(&gpio->port_config); | ||
370 | ul &= 0xFFFFFF8F; | ||
371 | ul |= 0x00000060; | ||
372 | out_be32(&gpio->port_config, ul); | ||
373 | out_be16(&cdm->mclken_div_psc2, mclken_div); | ||
374 | ul = in_be32(&cdm->clk_enables); | ||
375 | ul |= 0x00000040; | ||
376 | out_be32(&cdm->clk_enables, ul); | ||
377 | break; | ||
378 | case 3: | ||
379 | ul = in_be32(&gpio->port_config); | ||
380 | ul &= 0xFFFFF0FF; | ||
381 | ul |= 0x00000600; | ||
382 | out_be32(&gpio->port_config, ul); | ||
383 | out_be16(&cdm->mclken_div_psc3, mclken_div); | ||
384 | ul = in_be32(&cdm->clk_enables); | ||
385 | ul |= 0x00000080; | ||
386 | out_be32(&cdm->clk_enables, ul); | ||
387 | break; | ||
388 | case 6: | ||
389 | ul = in_be32(&gpio->port_config); | ||
390 | ul &= 0xFF8FFFFF; | ||
391 | ul |= 0x00700000; | ||
392 | out_be32(&gpio->port_config, ul); | ||
393 | out_be16(&cdm->mclken_div_psc6, mclken_div); | ||
394 | ul = in_be32(&cdm->clk_enables); | ||
395 | ul |= 0x00000010; | ||
396 | out_be32(&cdm->clk_enables, ul); | ||
397 | break; | ||
398 | default: | ||
399 | ret = -EINVAL; | ||
400 | goto unmap_regs; | ||
401 | } | ||
402 | 340 | ||
403 | /* Reset the PSC into a known state */ | 341 | /* Reset the PSC into a known state */ |
404 | out_8(&psc->command, MPC52xx_PSC_RST_RX); | 342 | out_8(&psc->command, MPC52xx_PSC_RST_RX); |
@@ -422,12 +360,6 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) | |||
422 | 360 | ||
423 | mps->bits_per_word = 8; | 361 | mps->bits_per_word = 8; |
424 | 362 | ||
425 | unmap_regs: | ||
426 | if (cdm) | ||
427 | iounmap(cdm); | ||
428 | if (gpio) | ||
429 | iounmap(gpio); | ||
430 | |||
431 | return ret; | 363 | return ret; |
432 | } | 364 | } |
433 | 365 | ||
@@ -623,8 +555,9 @@ static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op) | |||
623 | } | 555 | } |
624 | 556 | ||
625 | static struct of_device_id mpc52xx_psc_spi_of_match[] = { | 557 | static struct of_device_id mpc52xx_psc_spi_of_match[] = { |
626 | { .type = "spi", .compatible = "mpc5200-psc-spi", }, | 558 | { .compatible = "fsl,mpc5200-psc-spi", }, |
627 | {}, | 559 | { .compatible = "mpc5200-psc-spi", }, /* old */ |
560 | {} | ||
628 | }; | 561 | }; |
629 | 562 | ||
630 | MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match); | 563 | MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match); |
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c index 4580b9cf625d..04f7cd9fc261 100644 --- a/drivers/spi/spi_mpc83xx.c +++ b/drivers/spi/spi_mpc83xx.c | |||
@@ -436,11 +436,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev) | |||
436 | mpc83xx_spi->qe_mode = pdata->qe_mode; | 436 | mpc83xx_spi->qe_mode = pdata->qe_mode; |
437 | mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; | 437 | mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; |
438 | mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; | 438 | mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; |
439 | 439 | mpc83xx_spi->spibrg = pdata->sysclk; | |
440 | if (mpc83xx_spi->qe_mode) | ||
441 | mpc83xx_spi->spibrg = pdata->sysclk / 2; | ||
442 | else | ||
443 | mpc83xx_spi->spibrg = pdata->sysclk; | ||
444 | 440 | ||
445 | mpc83xx_spi->rx_shift = 0; | 441 | mpc83xx_spi->rx_shift = 0; |
446 | mpc83xx_spi->tx_shift = 0; | 442 | mpc83xx_spi->tx_shift = 0; |
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 0c3e6b790b7b..a67252791223 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c | |||
@@ -136,6 +136,8 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | |||
136 | ohci = hcd_to_ohci(hcd); | 136 | ohci = hcd_to_ohci(hcd); |
137 | if (is_bigendian) { | 137 | if (is_bigendian) { |
138 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; | 138 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; |
139 | if (of_device_is_compatible(dn, "fsl,mpc5200-ohci")) | ||
140 | ohci->flags |= OHCI_QUIRK_FRAME_NO; | ||
139 | if (of_device_is_compatible(dn, "mpc5200-ohci")) | 141 | if (of_device_is_compatible(dn, "mpc5200-ohci")) |
140 | ohci->flags |= OHCI_QUIRK_FRAME_NO; | 142 | ohci->flags |= OHCI_QUIRK_FRAME_NO; |
141 | } | 143 | } |