diff options
| -rw-r--r-- | Documentation/powerpc/dts-bindings/fsl/mpic.txt | 42 | ||||
| -rw-r--r-- | arch/powerpc/boot/dts/mpc8315erdb.dts | 27 | ||||
| -rw-r--r-- | arch/powerpc/boot/dts/mpc8349emitx.dts | 82 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/gpio.h | 5 | ||||
| -rw-r--r-- | arch/powerpc/platforms/83xx/suspend.c | 52 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/cpm2_pic.c | 28 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 8 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/mpc8xxx_gpio.c | 21 |
8 files changed, 248 insertions, 17 deletions
diff --git a/Documentation/powerpc/dts-bindings/fsl/mpic.txt b/Documentation/powerpc/dts-bindings/fsl/mpic.txt new file mode 100644 index 000000000000..71e39cf3215b --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/mpic.txt | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | * OpenPIC and its interrupt numbers on Freescale's e500/e600 cores | ||
| 2 | |||
| 3 | The OpenPIC specification does not specify which interrupt source has to | ||
| 4 | become which interrupt number. This is up to the software implementation | ||
| 5 | of the interrupt controller. The only requirement is that every | ||
| 6 | interrupt source has to have an unique interrupt number / vector number. | ||
| 7 | To accomplish this the current implementation assigns the number zero to | ||
| 8 | the first source, the number one to the second source and so on until | ||
| 9 | all interrupt sources have their unique number. | ||
| 10 | Usually the assigned vector number equals the interrupt number mentioned | ||
| 11 | in the documentation for a given core / CPU. This is however not true | ||
| 12 | for the e500 cores (MPC85XX CPUs) where the documentation distinguishes | ||
| 13 | between internal and external interrupt sources and starts counting at | ||
| 14 | zero for both of them. | ||
| 15 | |||
| 16 | So what to write for external interrupt source X or internal interrupt | ||
| 17 | source Y into the device tree? Here is an example: | ||
| 18 | |||
| 19 | The memory map for the interrupt controller in the MPC8544[0] shows, | ||
| 20 | that the first interrupt source starts at 0x5_0000 (PIC Register Address | ||
| 21 | Map-Interrupt Source Configuration Registers). This source becomes the | ||
| 22 | number zero therefore: | ||
| 23 | External interrupt 0 = interrupt number 0 | ||
| 24 | External interrupt 1 = interrupt number 1 | ||
| 25 | External interrupt 2 = interrupt number 2 | ||
| 26 | ... | ||
| 27 | Every interrupt number allocates 0x20 bytes register space. So to get | ||
| 28 | its number it is sufficient to shift the lower 16bits to right by five. | ||
| 29 | So for the external interrupt 10 we have: | ||
| 30 | 0x0140 >> 5 = 10 | ||
| 31 | |||
| 32 | After the external sources, the internal sources follow. The in core I2C | ||
| 33 | controller on the MPC8544 for instance has the internal source number | ||
| 34 | 27. Oo obtain its interrupt number we take the lower 16bits of its memory | ||
| 35 | address (0x5_0560) and shift it right: | ||
| 36 | 0x0560 >> 5 = 43 | ||
| 37 | |||
| 38 | Therefore the I2C device node for the MPC8544 CPU has to have the | ||
| 39 | interrupt number 43 specified in the device tree. | ||
| 40 | |||
| 41 | [0] MPC8544E PowerQUICCTM III, Integrated Host Processor Family Reference Manual | ||
| 42 | MPC8544ERM Rev. 1 10/2007 | ||
diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 32e10f588c1d..8a3a4f3ef831 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts | |||
| @@ -204,6 +204,7 @@ | |||
| 204 | interrupt-parent = <&ipic>; | 204 | interrupt-parent = <&ipic>; |
| 205 | tbi-handle = <&tbi0>; | 205 | tbi-handle = <&tbi0>; |
| 206 | phy-handle = < &phy0 >; | 206 | phy-handle = < &phy0 >; |
| 207 | fsl,magic-packet; | ||
| 207 | 208 | ||
| 208 | mdio@520 { | 209 | mdio@520 { |
| 209 | #address-cells = <1>; | 210 | #address-cells = <1>; |
| @@ -246,6 +247,7 @@ | |||
| 246 | interrupt-parent = <&ipic>; | 247 | interrupt-parent = <&ipic>; |
| 247 | tbi-handle = <&tbi1>; | 248 | tbi-handle = <&tbi1>; |
| 248 | phy-handle = < &phy1 >; | 249 | phy-handle = < &phy1 >; |
| 250 | fsl,magic-packet; | ||
| 249 | 251 | ||
| 250 | mdio@520 { | 252 | mdio@520 { |
| 251 | #address-cells = <1>; | 253 | #address-cells = <1>; |
| @@ -309,6 +311,22 @@ | |||
| 309 | interrupt-parent = <&ipic>; | 311 | interrupt-parent = <&ipic>; |
| 310 | }; | 312 | }; |
| 311 | 313 | ||
| 314 | gtm1: timer@500 { | ||
| 315 | compatible = "fsl,mpc8315-gtm", "fsl,gtm"; | ||
| 316 | reg = <0x500 0x100>; | ||
| 317 | interrupts = <90 8 78 8 84 8 72 8>; | ||
| 318 | interrupt-parent = <&ipic>; | ||
| 319 | clock-frequency = <133333333>; | ||
| 320 | }; | ||
| 321 | |||
| 322 | timer@600 { | ||
| 323 | compatible = "fsl,mpc8315-gtm", "fsl,gtm"; | ||
| 324 | reg = <0x600 0x100>; | ||
| 325 | interrupts = <91 8 79 8 85 8 73 8>; | ||
| 326 | interrupt-parent = <&ipic>; | ||
| 327 | clock-frequency = <133333333>; | ||
| 328 | }; | ||
| 329 | |||
| 312 | /* IPIC | 330 | /* IPIC |
| 313 | * interrupts cell = <intr #, sense> | 331 | * interrupts cell = <intr #, sense> |
| 314 | * sense values match linux IORESOURCE_IRQ_* defines: | 332 | * sense values match linux IORESOURCE_IRQ_* defines: |
| @@ -337,6 +355,15 @@ | |||
| 337 | 0x59 0x8>; | 355 | 0x59 0x8>; |
| 338 | interrupt-parent = < &ipic >; | 356 | interrupt-parent = < &ipic >; |
| 339 | }; | 357 | }; |
| 358 | |||
| 359 | pmc: power@b00 { | ||
| 360 | compatible = "fsl,mpc8315-pmc", "fsl,mpc8313-pmc", | ||
| 361 | "fsl,mpc8349-pmc"; | ||
| 362 | reg = <0xb00 0x100 0xa00 0x100>; | ||
| 363 | interrupts = <80 8>; | ||
| 364 | interrupt-parent = <&ipic>; | ||
| 365 | fsl,mpc8313-wakeup-timer = <>m1>; | ||
| 366 | }; | ||
| 340 | }; | 367 | }; |
| 341 | 368 | ||
| 342 | pci0: pci@e0008500 { | 369 | pci0: pci@e0008500 { |
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index feeeb7f9d609..b53d1df11e2d 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts | |||
| @@ -63,6 +63,24 @@ | |||
| 63 | reg = <0x200 0x100>; | 63 | reg = <0x200 0x100>; |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | gpio1: gpio-controller@c00 { | ||
| 67 | #gpio-cells = <2>; | ||
| 68 | compatible = "fsl,mpc8349-gpio"; | ||
| 69 | reg = <0xc00 0x100>; | ||
| 70 | interrupts = <74 0x8>; | ||
| 71 | interrupt-parent = <&ipic>; | ||
| 72 | gpio-controller; | ||
| 73 | }; | ||
| 74 | |||
| 75 | gpio2: gpio-controller@d00 { | ||
| 76 | #gpio-cells = <2>; | ||
| 77 | compatible = "fsl,mpc8349-gpio"; | ||
| 78 | reg = <0xd00 0x100>; | ||
| 79 | interrupts = <75 0x8>; | ||
| 80 | interrupt-parent = <&ipic>; | ||
| 81 | gpio-controller; | ||
| 82 | }; | ||
| 83 | |||
| 66 | i2c@3000 { | 84 | i2c@3000 { |
| 67 | #address-cells = <1>; | 85 | #address-cells = <1>; |
| 68 | #size-cells = <0>; | 86 | #size-cells = <0>; |
| @@ -72,6 +90,12 @@ | |||
| 72 | interrupts = <14 0x8>; | 90 | interrupts = <14 0x8>; |
| 73 | interrupt-parent = <&ipic>; | 91 | interrupt-parent = <&ipic>; |
| 74 | dfsrr; | 92 | dfsrr; |
| 93 | |||
| 94 | eeprom: at24@50 { | ||
| 95 | compatible = "st-micro,24c256"; | ||
| 96 | reg = <0x50>; | ||
| 97 | }; | ||
| 98 | |||
| 75 | }; | 99 | }; |
| 76 | 100 | ||
| 77 | i2c@3100 { | 101 | i2c@3100 { |
| @@ -91,6 +115,25 @@ | |||
| 91 | interrupt-parent = <&ipic>; | 115 | interrupt-parent = <&ipic>; |
| 92 | }; | 116 | }; |
| 93 | 117 | ||
| 118 | pcf1: iexp@38 { | ||
| 119 | #gpio-cells = <2>; | ||
| 120 | compatible = "ti,pcf8574a"; | ||
| 121 | reg = <0x38>; | ||
| 122 | gpio-controller; | ||
| 123 | }; | ||
| 124 | |||
| 125 | pcf2: iexp@39 { | ||
| 126 | #gpio-cells = <2>; | ||
| 127 | compatible = "ti,pcf8574a"; | ||
| 128 | reg = <0x39>; | ||
| 129 | gpio-controller; | ||
| 130 | }; | ||
| 131 | |||
| 132 | spd: at24@51 { | ||
| 133 | compatible = "at24,spd"; | ||
| 134 | reg = <0x51>; | ||
| 135 | }; | ||
| 136 | |||
| 94 | mcu_pio: mcu@a { | 137 | mcu_pio: mcu@a { |
| 95 | #gpio-cells = <2>; | 138 | #gpio-cells = <2>; |
| 96 | compatible = "fsl,mc9s08qg8-mpc8349emitx", | 139 | compatible = "fsl,mc9s08qg8-mpc8349emitx", |
| @@ -275,6 +318,24 @@ | |||
| 275 | reg = <0x700 0x100>; | 318 | reg = <0x700 0x100>; |
| 276 | device_type = "ipic"; | 319 | device_type = "ipic"; |
| 277 | }; | 320 | }; |
| 321 | |||
| 322 | gpio-leds { | ||
| 323 | compatible = "gpio-leds"; | ||
| 324 | |||
| 325 | green { | ||
| 326 | label = "Green"; | ||
| 327 | gpios = <&pcf1 0 1>; | ||
| 328 | linux,default-trigger = "heartbeat"; | ||
| 329 | }; | ||
| 330 | |||
| 331 | yellow { | ||
| 332 | label = "Yellow"; | ||
| 333 | gpios = <&pcf1 1 1>; | ||
| 334 | /* linux,default-trigger = "heartbeat"; */ | ||
| 335 | default-state = "on"; | ||
| 336 | }; | ||
| 337 | }; | ||
| 338 | |||
| 278 | }; | 339 | }; |
| 279 | 340 | ||
| 280 | pci0: pci@e0008500 { | 341 | pci0: pci@e0008500 { |
| @@ -331,7 +392,26 @@ | |||
| 331 | compatible = "fsl,mpc8349e-localbus", | 392 | compatible = "fsl,mpc8349e-localbus", |
| 332 | "fsl,pq2pro-localbus"; | 393 | "fsl,pq2pro-localbus"; |
| 333 | reg = <0xe0005000 0xd8>; | 394 | reg = <0xe0005000 0xd8>; |
| 334 | ranges = <0x3 0x0 0xf0000000 0x210>; | 395 | ranges = <0x0 0x0 0xfe000000 0x1000000 /* flash */ |
| 396 | 0x1 0x0 0xf8000000 0x20000 /* VSC 7385 */ | ||
| 397 | 0x2 0x0 0xf9000000 0x200000 /* exp slot */ | ||
| 398 | 0x3 0x0 0xf0000000 0x210>; /* CF slot */ | ||
| 399 | |||
| 400 | flash@0,0 { | ||
| 401 | compatible = "cfi-flash"; | ||
| 402 | reg = <0x0 0x0 0x800000>; | ||
| 403 | bank-width = <2>; | ||
| 404 | device-width = <1>; | ||
| 405 | }; | ||
| 406 | |||
| 407 | flash@0,800000 { | ||
| 408 | #address-cells = <1>; | ||
| 409 | #size-cells = <1>; | ||
| 410 | compatible = "cfi-flash"; | ||
| 411 | reg = <0x0 0x800000 0x800000>; | ||
| 412 | bank-width = <2>; | ||
| 413 | device-width = <1>; | ||
| 414 | }; | ||
| 335 | 415 | ||
| 336 | pata@3,0 { | 416 | pata@3,0 { |
| 337 | compatible = "fsl,mpc8349emitx-pata", "ata-generic"; | 417 | compatible = "fsl,mpc8349emitx-pata", "ata-generic"; |
diff --git a/arch/powerpc/include/asm/gpio.h b/arch/powerpc/include/asm/gpio.h index ea04632399d8..38762edb5e58 100644 --- a/arch/powerpc/include/asm/gpio.h +++ b/arch/powerpc/include/asm/gpio.h | |||
| @@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio) | |||
| 38 | return __gpio_cansleep(gpio); | 38 | return __gpio_cansleep(gpio); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | /* | ||
| 42 | * Not implemented, yet. | ||
| 43 | */ | ||
| 44 | static inline int gpio_to_irq(unsigned int gpio) | 41 | static inline int gpio_to_irq(unsigned int gpio) |
| 45 | { | 42 | { |
| 46 | return -ENOSYS; | 43 | return __gpio_to_irq(gpio); |
| 47 | } | 44 | } |
| 48 | 45 | ||
| 49 | static inline int irq_to_gpio(unsigned int irq) | 46 | static inline int irq_to_gpio(unsigned int irq) |
diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index d306f07b9aa1..43805348b81e 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */ | 32 | #define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */ |
| 33 | #define PMCCR1_NEXT_STATE_SHIFT 2 | 33 | #define PMCCR1_NEXT_STATE_SHIFT 2 |
| 34 | #define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/ | 34 | #define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/ |
| 35 | #define IMMR_SYSCR_OFFSET 0x100 | ||
| 35 | #define IMMR_RCW_OFFSET 0x900 | 36 | #define IMMR_RCW_OFFSET 0x900 |
| 36 | #define RCW_PCI_HOST 0x80000000 | 37 | #define RCW_PCI_HOST 0x80000000 |
| 37 | 38 | ||
| @@ -78,6 +79,22 @@ struct mpc83xx_clock { | |||
| 78 | u32 sccr; | 79 | u32 sccr; |
| 79 | }; | 80 | }; |
| 80 | 81 | ||
| 82 | struct mpc83xx_syscr { | ||
| 83 | __be32 sgprl; | ||
| 84 | __be32 sgprh; | ||
| 85 | __be32 spridr; | ||
| 86 | __be32 :32; | ||
| 87 | __be32 spcr; | ||
| 88 | __be32 sicrl; | ||
| 89 | __be32 sicrh; | ||
| 90 | }; | ||
| 91 | |||
| 92 | struct mpc83xx_saved { | ||
| 93 | u32 sicrl; | ||
| 94 | u32 sicrh; | ||
| 95 | u32 sccr; | ||
| 96 | }; | ||
| 97 | |||
| 81 | struct pmc_type { | 98 | struct pmc_type { |
| 82 | int has_deep_sleep; | 99 | int has_deep_sleep; |
| 83 | }; | 100 | }; |
| @@ -87,6 +104,8 @@ static int has_deep_sleep, deep_sleeping; | |||
| 87 | static int pmc_irq; | 104 | static int pmc_irq; |
| 88 | static struct mpc83xx_pmc __iomem *pmc_regs; | 105 | static struct mpc83xx_pmc __iomem *pmc_regs; |
| 89 | static struct mpc83xx_clock __iomem *clock_regs; | 106 | static struct mpc83xx_clock __iomem *clock_regs; |
| 107 | static struct mpc83xx_syscr __iomem *syscr_regs; | ||
| 108 | static struct mpc83xx_saved saved_regs; | ||
| 90 | static int is_pci_agent, wake_from_pci; | 109 | static int is_pci_agent, wake_from_pci; |
| 91 | static phys_addr_t immrbase; | 110 | static phys_addr_t immrbase; |
| 92 | static int pci_pm_state; | 111 | static int pci_pm_state; |
| @@ -137,6 +156,20 @@ static irqreturn_t pmc_irq_handler(int irq, void *dev_id) | |||
| 137 | return ret; | 156 | return ret; |
| 138 | } | 157 | } |
| 139 | 158 | ||
| 159 | static void mpc83xx_suspend_restore_regs(void) | ||
| 160 | { | ||
| 161 | out_be32(&syscr_regs->sicrl, saved_regs.sicrl); | ||
| 162 | out_be32(&syscr_regs->sicrh, saved_regs.sicrh); | ||
| 163 | out_be32(&clock_regs->sccr, saved_regs.sccr); | ||
| 164 | } | ||
| 165 | |||
| 166 | static void mpc83xx_suspend_save_regs(void) | ||
| 167 | { | ||
| 168 | saved_regs.sicrl = in_be32(&syscr_regs->sicrl); | ||
| 169 | saved_regs.sicrh = in_be32(&syscr_regs->sicrh); | ||
| 170 | saved_regs.sccr = in_be32(&clock_regs->sccr); | ||
| 171 | } | ||
| 172 | |||
| 140 | static int mpc83xx_suspend_enter(suspend_state_t state) | 173 | static int mpc83xx_suspend_enter(suspend_state_t state) |
| 141 | { | 174 | { |
| 142 | int ret = -EAGAIN; | 175 | int ret = -EAGAIN; |
| @@ -166,6 +199,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state) | |||
| 166 | */ | 199 | */ |
| 167 | 200 | ||
| 168 | if (deep_sleeping) { | 201 | if (deep_sleeping) { |
| 202 | mpc83xx_suspend_save_regs(); | ||
| 203 | |||
| 169 | out_be32(&pmc_regs->mask, PMCER_ALL); | 204 | out_be32(&pmc_regs->mask, PMCER_ALL); |
| 170 | 205 | ||
| 171 | out_be32(&pmc_regs->config1, | 206 | out_be32(&pmc_regs->config1, |
| @@ -179,6 +214,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state) | |||
| 179 | in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF); | 214 | in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF); |
| 180 | 215 | ||
| 181 | out_be32(&pmc_regs->mask, PMCER_PMCI); | 216 | out_be32(&pmc_regs->mask, PMCER_PMCI); |
| 217 | |||
| 218 | mpc83xx_suspend_restore_regs(); | ||
| 182 | } else { | 219 | } else { |
| 183 | out_be32(&pmc_regs->mask, PMCER_PMCI); | 220 | out_be32(&pmc_regs->mask, PMCER_PMCI); |
| 184 | 221 | ||
| @@ -194,7 +231,7 @@ out: | |||
| 194 | return ret; | 231 | return ret; |
| 195 | } | 232 | } |
| 196 | 233 | ||
| 197 | static void mpc83xx_suspend_finish(void) | 234 | static void mpc83xx_suspend_end(void) |
| 198 | { | 235 | { |
| 199 | deep_sleeping = 0; | 236 | deep_sleeping = 0; |
| 200 | } | 237 | } |
| @@ -278,7 +315,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { | |||
| 278 | .valid = mpc83xx_suspend_valid, | 315 | .valid = mpc83xx_suspend_valid, |
| 279 | .begin = mpc83xx_suspend_begin, | 316 | .begin = mpc83xx_suspend_begin, |
| 280 | .enter = mpc83xx_suspend_enter, | 317 | .enter = mpc83xx_suspend_enter, |
| 281 | .finish = mpc83xx_suspend_finish, | 318 | .end = mpc83xx_suspend_end, |
| 282 | }; | 319 | }; |
| 283 | 320 | ||
| 284 | static int pmc_probe(struct of_device *ofdev, | 321 | static int pmc_probe(struct of_device *ofdev, |
| @@ -333,12 +370,23 @@ static int pmc_probe(struct of_device *ofdev, | |||
| 333 | goto out_pmc; | 370 | goto out_pmc; |
| 334 | } | 371 | } |
| 335 | 372 | ||
| 373 | if (has_deep_sleep) { | ||
| 374 | syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET, | ||
| 375 | sizeof(*syscr_regs)); | ||
| 376 | if (!syscr_regs) { | ||
| 377 | ret = -ENOMEM; | ||
| 378 | goto out_syscr; | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 336 | if (is_pci_agent) | 382 | if (is_pci_agent) |
| 337 | mpc83xx_set_agent(); | 383 | mpc83xx_set_agent(); |
| 338 | 384 | ||
| 339 | suspend_set_ops(&mpc83xx_suspend_ops); | 385 | suspend_set_ops(&mpc83xx_suspend_ops); |
| 340 | return 0; | 386 | return 0; |
| 341 | 387 | ||
| 388 | out_syscr: | ||
| 389 | iounmap(clock_regs); | ||
| 342 | out_pmc: | 390 | out_pmc: |
| 343 | iounmap(pmc_regs); | 391 | iounmap(pmc_regs); |
| 344 | out: | 392 | out: |
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index 971483f0dfac..1709ac5aac7c 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c | |||
| @@ -143,13 +143,23 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) | |||
| 143 | struct irq_desc *desc = irq_to_desc(virq); | 143 | struct irq_desc *desc = irq_to_desc(virq); |
| 144 | unsigned int vold, vnew, edibit; | 144 | unsigned int vold, vnew, edibit; |
| 145 | 145 | ||
| 146 | if (flow_type == IRQ_TYPE_NONE) | 146 | /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or |
| 147 | flow_type = IRQ_TYPE_LEVEL_LOW; | 147 | * IRQ_TYPE_EDGE_BOTH (default). All others are IRQ_TYPE_EDGE_FALLING |
| 148 | 148 | * or IRQ_TYPE_LEVEL_LOW (default) | |
| 149 | if (flow_type & IRQ_TYPE_EDGE_RISING) { | 149 | */ |
| 150 | printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n", | 150 | if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) { |
| 151 | flow_type); | 151 | if (flow_type == IRQ_TYPE_NONE) |
| 152 | return -EINVAL; | 152 | flow_type = IRQ_TYPE_EDGE_BOTH; |
| 153 | |||
| 154 | if (flow_type != IRQ_TYPE_EDGE_BOTH && | ||
| 155 | flow_type != IRQ_TYPE_EDGE_FALLING) | ||
| 156 | goto err_sense; | ||
| 157 | } else { | ||
| 158 | if (flow_type == IRQ_TYPE_NONE) | ||
| 159 | flow_type = IRQ_TYPE_LEVEL_LOW; | ||
| 160 | |||
| 161 | if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) | ||
| 162 | goto err_sense; | ||
| 153 | } | 163 | } |
| 154 | 164 | ||
| 155 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); | 165 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); |
| @@ -181,6 +191,10 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) | |||
| 181 | if (vold != vnew) | 191 | if (vold != vnew) |
| 182 | out_be32(&cpm2_intctl->ic_siexr, vnew); | 192 | out_be32(&cpm2_intctl->ic_siexr, vnew); |
| 183 | return 0; | 193 | return 0; |
| 194 | |||
| 195 | err_sense: | ||
| 196 | pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type); | ||
| 197 | return -EINVAL; | ||
| 184 | } | 198 | } |
| 185 | 199 | ||
| 186 | static struct irq_chip cpm2_pic = { | 200 | static struct irq_chip cpm2_pic = { |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 4e3a3e345ab3..e1a028c1f18d 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
| @@ -464,8 +464,7 @@ static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus, | |||
| 464 | { | 464 | { |
| 465 | struct pci_controller *hose = pci_bus_to_host(bus); | 465 | struct pci_controller *hose = pci_bus_to_host(bus); |
| 466 | struct mpc83xx_pcie_priv *pcie = hose->dn->data; | 466 | struct mpc83xx_pcie_priv *pcie = hose->dn->data; |
| 467 | u8 bus_no = bus->number - hose->first_busno; | 467 | u32 dev_base = bus->number << 24 | devfn << 16; |
| 468 | u32 dev_base = bus_no << 24 | devfn << 16; | ||
| 469 | int ret; | 468 | int ret; |
| 470 | 469 | ||
| 471 | ret = mpc83xx_pcie_exclude_device(bus, devfn); | 470 | ret = mpc83xx_pcie_exclude_device(bus, devfn); |
| @@ -515,12 +514,17 @@ static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 515 | static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | 514 | static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, |
| 516 | int offset, int len, u32 val) | 515 | int offset, int len, u32 val) |
| 517 | { | 516 | { |
| 517 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
| 518 | void __iomem *cfg_addr; | 518 | void __iomem *cfg_addr; |
| 519 | 519 | ||
| 520 | cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); | 520 | cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); |
| 521 | if (!cfg_addr) | 521 | if (!cfg_addr) |
| 522 | return PCIBIOS_DEVICE_NOT_FOUND; | 522 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 523 | 523 | ||
| 524 | /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */ | ||
| 525 | if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno) | ||
| 526 | val &= 0xffffff00; | ||
| 527 | |||
| 524 | switch (len) { | 528 | switch (len) { |
| 525 | case 1: | 529 | case 1: |
| 526 | out_8(cfg_addr, val); | 530 | out_8(cfg_addr, val); |
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index 103eace36194..ee1c0e1cf4a7 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c | |||
| @@ -54,6 +54,22 @@ static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) | |||
| 54 | mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); | 54 | mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs | ||
| 58 | * defined as output cannot be determined by reading GPDAT register, | ||
| 59 | * so we use shadow data register instead. The status of input pins | ||
| 60 | * is determined by reading GPDAT register. | ||
| 61 | */ | ||
| 62 | static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
| 63 | { | ||
| 64 | u32 val; | ||
| 65 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
| 66 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
| 67 | |||
| 68 | val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR); | ||
| 69 | |||
| 70 | return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio); | ||
| 71 | } | ||
| 72 | |||
| 57 | static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) | 73 | static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) |
| 58 | { | 74 | { |
| 59 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | 75 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); |
| @@ -136,7 +152,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
| 136 | gc->ngpio = MPC8XXX_GPIO_PINS; | 152 | gc->ngpio = MPC8XXX_GPIO_PINS; |
| 137 | gc->direction_input = mpc8xxx_gpio_dir_in; | 153 | gc->direction_input = mpc8xxx_gpio_dir_in; |
| 138 | gc->direction_output = mpc8xxx_gpio_dir_out; | 154 | gc->direction_output = mpc8xxx_gpio_dir_out; |
| 139 | gc->get = mpc8xxx_gpio_get; | 155 | if (of_device_is_compatible(np, "fsl,mpc8572-gpio")) |
| 156 | gc->get = mpc8572_gpio_get; | ||
| 157 | else | ||
| 158 | gc->get = mpc8xxx_gpio_get; | ||
| 140 | gc->set = mpc8xxx_gpio_set; | 159 | gc->set = mpc8xxx_gpio_set; |
| 141 | 160 | ||
| 142 | ret = of_mm_gpiochip_add(np, mm_gc); | 161 | ret = of_mm_gpiochip_add(np, mm_gc); |
