LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [git pull] Please pull powerpc.git next branch
From: Benjamin Herrenschmidt @ 2011-11-06 23:35 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linuxppc-dev list, Andrew Morton, Linux Kernel list

Hi Linus !

Here's (finally) the powerpc stuff for this merge window. It's late, as
I warned you during KS, I was on vacation & travelling around and really
couldn't get to do it earlier than today. Everything in there has been
in linux-next for a while anyway, the only difference from what was in
github a month ago is that I merged a bit more freescale bits from
Kumar.

As for the highlights, you get the new "powernv" platform which allows
booting under the new "OPAL" firmware. This will allow booting without a
hypervisor on future IBM POWER machines, in order to be able to run KVM.
There's still one missing component to support the latest PCI Express
bridges, but it's a drop-in addition, so I might still merge it after
-rc1 (or not .. I haven't decided yet, I held on to it for a bit as it
was depending on some PCI changes that went upstream separately via
Jesse and dealing with the dependency while travelling was deemed too
annoying).

We also have a bunch of Numa fixes from Anton, some DMA code cleanup
from Milton and the usual batch of embedded bits and pieces.

Cheers,
Ben.
 
The following changes since commit d6748066ad0e8b2514545998f8367ebb3906f299:

  Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus (2011-11-03 13:28:14 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git next

Anatolij Gustschin (5):
      powerpc/5200: mpc5200b.dtsi: add spi node address- and size-cells properties
      powerpc/5200: dts: digsy_mtc.dts: update to add can, pci, serial and spi
      powerpc/5200: dts: digsy_mtc.dts: add timer0 and timer1 gpio properties
      powerpc/5200: dts: digsy_mtc.dts: enable both MSCAN nodes
      powerpc/85xx: fix PHYS_64BIT selection for P1022DS

Anshuman Khandual (1):
      perf events, powerpc: Add POWER7 stalled-cycles-frontend/backend events

Anton Blanchard (11):
      powerpc/pseries: Avoid spurious error during hotplug CPU add
      powerpc/numa: Enable SD_WAKE_AFFINE in node definition
      sched: Allow SD_NODES_PER_DOMAIN to be overridden
      powerpc/numa: Increase SD_NODES_PER_DOMAIN to 32.
      powerpc/numa: Disable NEWIDLE balancing at node level
      powerpc/numa: Remove duplicate RECLAIM_DISTANCE definition
      powerpc/numa: Remove double of_node_put in hot_add_node_scn_to_nid
      powerpc: Use for_each_node_by_type instead of open coding it
      powerpc: Coding style cleanups
      powerpc: Fix oops when echoing bad values to /sys/devices/system/memory/probe
      powerpc: Fix deadlock in icswx code

Arnaud Lacombe (1):
      powerpc/xics: Add __init to marker icp_native_init()

Arnd Bergmann (1):
      serial/8250: Move UPIO_TSI to powerpc

Ayman El-Khashab (1):
      powerpc/4xx: enable and fix pcie gen1/gen2 on the 460sx

Becky Bruce (4):
      powerpc: Hugetlb for BookE
      powerpc: Update mpc85xx/corenet 32-bit defconfigs
      powerpc: Update corenet64_smp_defconfig
      powerpc/fsl-booke: Fix settlbcam for 64-bit

Benjamin Herrenschmidt (27):
      Merge remote-tracking branch 'jwb/next' into next
      Merge remote-tracking branch 'origin/master' into next
      powerpc/wsp: Add PCIe Root support to PowerEN/WSP
      Merge remote-tracking branch 'origin/master' into next
      powerpc/udbg: Fix Kconfig entry for avoiding 44x early debug with KVM
      powerpc/smp: More generic support for "soft hotplug"
      powerpc/pci: Call pcie_bus_configure_settings()
      powerpc/powernv: Don't clobber r9 in relative_toc()
      powerpc: Add skeleton PowerNV platform
      of: Change logic to overwrite cmd_line with CONFIG_CMDLINE
      powerpc/powernv: Add CPU hotplug support
      powerpc/powernv: Add OPAL takeover from PowerVM
      powerpc/powernv: Get kernel command line accross OPAL takeover
      powerpc/powernv: Basic support for OPAL
      powerpc/powernv: Add support for instanciating OPAL v2 from Open Firmware
      powerpc/powernv: Support for OPAL console
      powerpc/powernv: Hookup reboot and poweroff functions
      powerpc/powernv: Add RTC and NVRAM support plus RTAS fallbacks
      powerpc/powernv: Add OPAL ICS backend
      powerpc/powernv: Register and handle OPAL interrupts
      powerpc/powernv: Machine check and other system interrupts
      powerpc/powernv: Add support for p5ioc2 PCI-X and PCIe
      powerpc/powernv: Implement MSI support for p5ioc2 PCIe
      powerpc/powernv: Handle PCI-X/PCIe reset delay
      powerpc/pci: Don't configure PCIe settings when PCI_PROBE_ONLY is set
      powerpc/ptrace: Fix build with gcc 4.6
      powerpc: Don't try OPAL takeover on old 970 blades

Bharat Bhushan (1):
      powerpc: e500mc: Fix: use CONFIG_PPC_E500MC in idle_e500.S

Brian King (1):
      hvcs: Ensure page aligned partner info buffer

Carl E. Love (1):
      powerpc/perf_event: Fix Power6 L1 cache read & write event codes]

Dmitry Eremin-Solenikov (5):
      cpc925_edac: Support single-processor configurations
      powerpc/85xx: sbc8560 - correct compilation if CONFIG_PHYS_ADDR_T_64BIT is set
      powerpc/85xx: ksi8560 - declare that localbus is compatbile with simple-bus
      powerpc/85xx: sbc8560 - declare that localbus is compatbile with simple-bus
      powerpc/mpc8349emitx: mark localbus as compatible with simple-bus

Fabio Baltieri (1):
      powerpc/83xx: Add shutdown request support to MCU handling on MPC8349 MITX

Felix Radensky (1):
      powerpc/8xxx: Fix interrupt handling in MPC8xxx GPIO driver

Hector Martin (1):
      powerpc/ps3: Add gelic udbg driver

Holger Brunck (1):
      powerpc/82xx: updates for mgcoge

Hongjun Chen (1):
      powerpc/cpm: Clear muram before it is in use.

Jim Keniston (1):
      powerpc/nvram: Add compression to fit more oops output into NVRAM

Jimi Xenidis (2):
      powerpc/wsp: Fix Wire Speed Processor platform configs
      powerpc: Fix xmon for systems without MSR[RI]

Josh Boyer (1):
      powerpc/40x: Remove obsolete HCU4 board

Julia Lawall (1):
      pseries/iommu: Add missing kfree

Kumar Gala (6):
      powerpc/85xx: Rename PowerPC core nodes to match other e500mc based .dts
      powerpc/fsl-booke: Handle L1 D-cache parity error correctly on e500mc
      powerpc: respect mem= setting for early memory limit setup
      powerpc/fsl-booke: Fix setup_initial_memory_limit to not blindly map
      powerpc/85xx: Setup secondary cores PIR with hard SMP id
      powerpc/85xx: Add 'fsl,pq3-gpio' compatiable for GPIO driver

Liu Yu (3):
      powerpc/math_emu/efp: Use pr_debug instead of printk
      powerpc/math_emu/efp: No need to round if the result is exact
      powerpc/math_emu/efp: Look for errata handler when type mismatches

Martyn Welch (1):
      powerpc/86xx: Correct Gianfar support for GE boards

Matthew McClintock (5):
      powerpc: Fix build dependencies for epapr.c which needs libfdt.h
      powerpc/85xx: Fix support for enabling doorbells for IPIs
      powerpc/85xx: issue 15 EOI after core reset for FSL CoreNet devices
      powerpc/fsl_booke: Fix comment in head_fsl_booke.S
      powerpc/85xx: Make kexec to interate over online cpus

Michael Ellerman (1):
      powerpc/wsp: Add MSI support for PCI on PowerEN

Mihai Caraman (1):
      drivers/virt: add ioctl for 32-bit compat on 64-bit to fsl-hv-manager

Mike Williams (1):
      powerpc/4xx: edac: Add comma to fix build error

Milton Miller (4):
      powerpc: Override dma_get_required_mask by platform hook and ops
      dma-mapping: Add get_required_mask if arch overrides default
      powerpc: Use the newly added get_required_mask dma_map_ops hook
      powerpc: Tidy up dma_map_ops after adding new hook

Mingkai Hu (1):
      powerpc/85xx: Rename p2040_rdb.c to p2041_rdb.c

Paul Mackerras (1):
      powerpc: Fix hugetlb with CONFIG_PPC_MM_SLICES=y

Scott Wood (1):
      powerpc/32: Pass device tree address as u64 to machine_init

Shengzhou Liu (1):
      powerpc/p3060qds: Add support for P3060QDS board

Stefan Roese (1):
      powerpc/44x: Add NOR flash device to Yosemite dts

Stephen George (1):
      powerpc/85xx: Adding DCSR node to dtsi device trees

Suzuki Poulose (1):
      powerpc/44x: Kexec support for PPC440X chipsets

Tang Yuantian (1):
      powerpc/mm: Fix the call trace when resumed from hibernation

Thadeu Lima de Souza Cascardo (2):
      powerpc/eeh: Fix /proc/ppc64/eeh creation
      powerpc: Reserve iommu page 0

Timur Tabi (5):
      powerpc/mpic: Add support for discontiguous cores
      powerpc/5200: enable audio in the defconfig
      powerpc/fsl_msi: fix support for multiple MSI ranges
      powerpc/85xx: clean up FPGA device tree nodes for Freecsale QorIQ boards
      powerpc/fsl_msi: add support for "msi-address-64" property

Tony Breeds (1):
      powerpc/4xx/pci: Add __init annotations for *init_port_hw() functions.

Wolfram Sang (2):
      gpio: move mpc8xxx/512x gpio driver to drivers/gpio
      powerpc: update 512x-defconfig

 .../devicetree/bindings/powerpc/fsl/board.txt      |   30 +-
 .../devicetree/bindings/powerpc/fsl/dcsr.txt       |  395 +++++++
 .../devicetree/bindings/powerpc/fsl/msi-pic.txt    |   42 +
 arch/powerpc/Kconfig                               |    7 +-
 arch/powerpc/Kconfig.debug                         |   46 +-
 arch/powerpc/boot/Makefile                         |    3 +-
 arch/powerpc/boot/dts/digsy_mtc.dts                |   59 +-
 arch/powerpc/boot/dts/gef_ppc9a.dts                |   33 +-
 arch/powerpc/boot/dts/gef_sbc310.dts               |   33 +-
 arch/powerpc/boot/dts/gef_sbc610.dts               |   33 +-
 arch/powerpc/boot/dts/hcu4.dts                     |  168 ---
 arch/powerpc/boot/dts/ksi8560.dts                  |    2 +-
 arch/powerpc/boot/dts/mgcoge.dts                   |    9 +
 arch/powerpc/boot/dts/mpc5200b.dtsi                |    2 +
 arch/powerpc/boot/dts/mpc8349emitx.dts             |    3 +-
 arch/powerpc/boot/dts/p1022ds.dts                  |    2 +-
 arch/powerpc/boot/dts/p2020ds.dts                  |    5 +
 .../boot/dts/{p2040rdb.dts => p2041rdb.dts}        |   17 +-
 .../boot/dts/{p2040si.dtsi => p2041si.dtsi}        |  135 ++-
 arch/powerpc/boot/dts/p3041ds.dts                  |    8 +-
 arch/powerpc/boot/dts/p3041si.dtsi                 |   71 ++-
 arch/powerpc/boot/dts/p3060qds.dts                 |  238 ++++
 arch/powerpc/boot/dts/p3060si.dtsi                 |  719 +++++++++++++
 arch/powerpc/boot/dts/p4080ds.dts                  |   12 +-
 arch/powerpc/boot/dts/p4080si.dtsi                 |  114 ++-
 arch/powerpc/boot/dts/p5020ds.dts                  |    8 +-
 arch/powerpc/boot/dts/p5020si.dtsi                 |   68 ++-
 arch/powerpc/boot/dts/sbc8560.dts                  |    2 +-
 arch/powerpc/boot/dts/yosemite.dts                 |   36 +
 arch/powerpc/configs/40x/hcu4_defconfig            |   80 --
 arch/powerpc/configs/85xx/p1023rds_defconfig       |    2 +-
 arch/powerpc/configs/85xx/xes_mpc85xx_defconfig    |    2 +-
 arch/powerpc/configs/corenet32_smp_defconfig       |   11 +-
 arch/powerpc/configs/corenet64_smp_defconfig       |    5 -
 arch/powerpc/configs/mgcoge_defconfig              |   27 +-
 arch/powerpc/configs/mpc512x_defconfig             |   19 +-
 arch/powerpc/configs/mpc5200_defconfig             |   12 +
 arch/powerpc/configs/mpc85xx_defconfig             |    5 +-
 arch/powerpc/configs/mpc85xx_smp_defconfig         |    6 +-
 arch/powerpc/configs/ppc40x_defconfig              |    1 -
 arch/powerpc/configs/ppc6xx_defconfig              |    2 +-
 arch/powerpc/include/asm/device.h                  |    2 +
 arch/powerpc/include/asm/firmware.h                |   10 +
 arch/powerpc/include/asm/hugetlb.h                 |   63 ++-
 arch/powerpc/include/asm/kexec.h                   |    2 +-
 arch/powerpc/include/asm/machdep.h                 |    3 +-
 arch/powerpc/include/asm/mmu-book3e.h              |    7 +
 arch/powerpc/include/asm/mmu-hash64.h              |    3 +-
 arch/powerpc/include/asm/mmu.h                     |   18 +-
 arch/powerpc/include/asm/mpic.h                    |    2 -
 arch/powerpc/include/asm/opal.h                    |  443 ++++++++
 arch/powerpc/include/asm/paca.h                    |    8 +
 arch/powerpc/include/asm/page.h                    |   31 +-
 arch/powerpc/include/asm/page_64.h                 |   11 -
 arch/powerpc/include/asm/pte-book3e.h              |    3 +
 arch/powerpc/include/asm/reg_booke.h               |    3 +
 arch/powerpc/include/asm/rtas.h                    |    6 +-
 arch/powerpc/include/asm/smp.h                     |    1 +
 arch/powerpc/include/asm/sparsemem.h               |    2 +-
 arch/powerpc/include/asm/topology.h                |   14 +-
 arch/powerpc/include/asm/udbg.h                    |    3 +
 arch/powerpc/include/asm/xics.h                    |   19 +
 arch/powerpc/kernel/asm-offsets.c                  |   10 +
 arch/powerpc/kernel/dma-iommu.c                    |   28 +-
 arch/powerpc/kernel/dma-swiotlb.c                  |   16 +
 arch/powerpc/kernel/dma.c                          |   44 +-
 arch/powerpc/kernel/exceptions-64s.S               |   27 +-
 arch/powerpc/kernel/head_32.S                      |    7 +-
 arch/powerpc/kernel/head_40x.S                     |   15 +-
 arch/powerpc/kernel/head_44x.S                     |   16 +-
 arch/powerpc/kernel/head_64.S                      |   22 +-
 arch/powerpc/kernel/head_8xx.S                     |   13 +-
 arch/powerpc/kernel/head_fsl_booke.S               |  175 +++-
 arch/powerpc/kernel/ibmebus.c                      |   22 +-
 arch/powerpc/kernel/idle_e500.S                    |    2 +-
 arch/powerpc/kernel/iommu.c                        |    8 +
 arch/powerpc/kernel/legacy_serial.c                |   25 +
 arch/powerpc/kernel/machine_kexec_64.c             |    3 +-
 arch/powerpc/kernel/misc_32.S                      |  171 +++
 arch/powerpc/kernel/pci-common.c                   |   11 +
 arch/powerpc/kernel/power6-pmu.c                   |    4 +-
 arch/powerpc/kernel/power7-pmu.c                   |    2 +
 arch/powerpc/kernel/prom.c                         |   19 +-
 arch/powerpc/kernel/prom_init.c                    |  383 ++++++-
 arch/powerpc/kernel/prom_init_check.sh             |    4 +-
 arch/powerpc/kernel/ptrace.c                       |   18 +-
 arch/powerpc/kernel/setup_32.c                     |    2 +-
 arch/powerpc/kernel/setup_64.c                     |   22 +-
 arch/powerpc/kernel/smp.c                          |   30 +-
 arch/powerpc/kernel/swsusp.c                       |    2 +-
 arch/powerpc/kernel/traps.c                        |    9 +-
 arch/powerpc/kernel/udbg.c                         |    6 +
 arch/powerpc/kernel/vio.c                          |   21 +-
 arch/powerpc/math-emu/math_efp.c                   |  100 +-
 arch/powerpc/mm/Makefile                           |    1 +
 arch/powerpc/mm/fsl_booke_mmu.c                    |   43 +-
 arch/powerpc/mm/hash_utils_64.c                    |    9 +-
 arch/powerpc/mm/hugetlbpage-book3e.c               |  121 +++
 arch/powerpc/mm/hugetlbpage.c                      |  379 ++++++-
 arch/powerpc/mm/init_32.c                          |    9 +
 arch/powerpc/mm/mem.c                              |    8 +-
 arch/powerpc/mm/mmu_context_hash64.c               |   12 +-
 arch/powerpc/mm/mmu_context_nohash.c               |    5 +
 arch/powerpc/mm/mmu_decl.h                         |    2 +
 arch/powerpc/mm/numa.c                             |   20 +-
 arch/powerpc/mm/pgtable.c                          |    3 +-
 arch/powerpc/mm/tlb_low_64e.S                      |   24 +-
 arch/powerpc/mm/tlb_nohash.c                       |   67 ++-
 arch/powerpc/platforms/40x/Kconfig                 |    8 -
 arch/powerpc/platforms/40x/Makefile                |    1 -
 arch/powerpc/platforms/40x/hcu4.c                  |   61 --
 arch/powerpc/platforms/512x/Kconfig                |    1 +
 arch/powerpc/platforms/82xx/km82xx.c               |    4 +
 arch/powerpc/platforms/83xx/Kconfig                |    9 +-
 arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c     |   58 +-
 arch/powerpc/platforms/85xx/Kconfig                |   32 +-
 arch/powerpc/platforms/85xx/Makefile               |    3 +-
 arch/powerpc/platforms/85xx/p1022_ds.c             |   11 +-
 .../platforms/85xx/{p2040_rdb.c => p2041_rdb.c}    |   18 +-
 arch/powerpc/platforms/85xx/p3060_qds.c            |   77 ++
 arch/powerpc/platforms/85xx/sbc8560.c              |    2 +-
 arch/powerpc/platforms/85xx/smp.c                  |   12 +-
 arch/powerpc/platforms/86xx/Kconfig                |    1 +
 arch/powerpc/platforms/Kconfig                     |   13 +-
 arch/powerpc/platforms/Kconfig.cputype             |    4 +-
 arch/powerpc/platforms/Makefile                    |    1 +
 arch/powerpc/platforms/cell/iommu.c                |   21 +
 arch/powerpc/platforms/powernv/Kconfig             |   16 +
 arch/powerpc/platforms/powernv/Makefile            |    5 +
 arch/powerpc/platforms/powernv/opal-nvram.c        |   88 ++
 arch/powerpc/platforms/powernv/opal-rtc.c          |   97 ++
 arch/powerpc/platforms/powernv/opal-takeover.S     |  140 +++
 arch/powerpc/platforms/powernv/opal-wrappers.S     |  101 ++
 arch/powerpc/platforms/powernv/opal.c              |  322 ++++++
 arch/powerpc/platforms/powernv/pci-p5ioc2.c        |  234 ++++
 arch/powerpc/platforms/powernv/pci.c               |  427 ++++++++
 arch/powerpc/platforms/powernv/pci.h               |   48 +
 arch/powerpc/platforms/powernv/powernv.h           |   16 +
 arch/powerpc/platforms/powernv/setup.c             |  196 ++++
 arch/powerpc/platforms/powernv/smp.c               |  182 ++++
 arch/powerpc/platforms/ps3/Kconfig                 |   12 +
 arch/powerpc/platforms/ps3/Makefile                |    1 +
 arch/powerpc/platforms/ps3/gelic_udbg.c            |  273 +++++
 arch/powerpc/platforms/ps3/system-bus.c            |    7 +
 arch/powerpc/platforms/pseries/Kconfig             |    1 +
 arch/powerpc/platforms/pseries/dlpar.c             |    4 +
 arch/powerpc/platforms/pseries/eeh.c               |    2 +-
 arch/powerpc/platforms/pseries/iommu.c             |   34 +-
 arch/powerpc/platforms/pseries/nvram.c             |  171 +++-
 arch/powerpc/platforms/wsp/Kconfig                 |   11 +-
 arch/powerpc/platforms/wsp/Makefile                |    2 +
 arch/powerpc/platforms/wsp/ics.c                   |   48 +
 arch/powerpc/platforms/wsp/ics.h                   |    5 +
 arch/powerpc/platforms/wsp/msi.c                   |  102 ++
 arch/powerpc/platforms/wsp/msi.h                   |   19 +
 arch/powerpc/platforms/wsp/psr2.c                  |    4 +
 arch/powerpc/platforms/wsp/wsp.h                   |    3 +
 arch/powerpc/platforms/wsp/wsp_pci.c               | 1133 ++++++++++++++++++++
 arch/powerpc/platforms/wsp/wsp_pci.h               |  268 +++++
 arch/powerpc/sysdev/Makefile                       |    1 -
 arch/powerpc/sysdev/cpm_common.c                   |    3 +-
 arch/powerpc/sysdev/fsl_msi.c                      |   28 +-
 arch/powerpc/sysdev/fsl_msi.h                      |    3 +-
 arch/powerpc/sysdev/mpic.c                         |   34 +-
 arch/powerpc/sysdev/ppc4xx_pci.c                   |  101 ++-
 arch/powerpc/sysdev/ppc4xx_pci.h                   |   12 +
 arch/powerpc/sysdev/xics/Makefile                  |    1 +
 arch/powerpc/sysdev/xics/icp-native.c              |    2 +-
 arch/powerpc/sysdev/xics/ics-opal.c                |  244 +++++
 arch/powerpc/sysdev/xics/xics-common.c             |    8 +-
 arch/powerpc/xmon/xmon.c                           |    4 +-
 drivers/edac/cpc925_edac.c                         |   67 ++-
 drivers/edac/ppc4xx_edac.c                         |    2 +-
 drivers/gpio/Kconfig                               |    8 +
 drivers/gpio/Makefile                              |    1 +
 .../mpc8xxx_gpio.c => drivers/gpio/gpio-mpc8xxx.c  |    3 +
 drivers/net/ps3_gelic_net.c                        |    3 +
 drivers/net/ps3_gelic_net.h                        |    6 +
 drivers/of/fdt.c                                   |    7 +-
 drivers/tty/hvc/Kconfig                            |    9 +
 drivers/tty/hvc/Makefile                           |    1 +
 drivers/tty/hvc/hvc_opal.c                         |  424 ++++++++
 drivers/tty/hvc/hvcs.c                             |    6 +-
 drivers/tty/hvc/hvsi_lib.c                         |    4 +-
 drivers/tty/serial/8250.c                          |   23 -
 drivers/virt/fsl_hypervisor.c                      |    1 +
 include/linux/dma-mapping.h                        |    3 +
 include/linux/topology.h                           |    4 +
 kernel/sched.c                                     |    2 -
 189 files changed, 9411 insertions(+), 979 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/dcsr.txt
 delete mode 100644 arch/powerpc/boot/dts/hcu4.dts
 rename arch/powerpc/boot/dts/{p2040rdb.dts => p2041rdb.dts} (95%)
 rename arch/powerpc/boot/dts/{p2040si.dtsi => p2041si.dtsi} (80%)
 create mode 100644 arch/powerpc/boot/dts/p3060qds.dts
 create mode 100644 arch/powerpc/boot/dts/p3060si.dtsi
 delete mode 100644 arch/powerpc/configs/40x/hcu4_defconfig
 create mode 100644 arch/powerpc/include/asm/opal.h
 create mode 100644 arch/powerpc/mm/hugetlbpage-book3e.c
 delete mode 100644 arch/powerpc/platforms/40x/hcu4.c
 rename arch/powerpc/platforms/85xx/{p2040_rdb.c => p2041_rdb.c} (82%)
 create mode 100644 arch/powerpc/platforms/85xx/p3060_qds.c
 create mode 100644 arch/powerpc/platforms/powernv/Kconfig
 create mode 100644 arch/powerpc/platforms/powernv/Makefile
 create mode 100644 arch/powerpc/platforms/powernv/opal-nvram.c
 create mode 100644 arch/powerpc/platforms/powernv/opal-rtc.c
 create mode 100644 arch/powerpc/platforms/powernv/opal-takeover.S
 create mode 100644 arch/powerpc/platforms/powernv/opal-wrappers.S
 create mode 100644 arch/powerpc/platforms/powernv/opal.c
 create mode 100644 arch/powerpc/platforms/powernv/pci-p5ioc2.c
 create mode 100644 arch/powerpc/platforms/powernv/pci.c
 create mode 100644 arch/powerpc/platforms/powernv/pci.h
 create mode 100644 arch/powerpc/platforms/powernv/powernv.h
 create mode 100644 arch/powerpc/platforms/powernv/setup.c
 create mode 100644 arch/powerpc/platforms/powernv/smp.c
 create mode 100644 arch/powerpc/platforms/ps3/gelic_udbg.c
 create mode 100644 arch/powerpc/platforms/wsp/msi.c
 create mode 100644 arch/powerpc/platforms/wsp/msi.h
 create mode 100644 arch/powerpc/platforms/wsp/wsp_pci.c
 create mode 100644 arch/powerpc/platforms/wsp/wsp_pci.h
 create mode 100644 arch/powerpc/sysdev/xics/ics-opal.c
 rename arch/powerpc/sysdev/mpc8xxx_gpio.c => drivers/gpio/gpio-mpc8xxx.c (98%)
 create mode 100644 drivers/tty/hvc/hvc_opal.c

^ permalink raw reply

* New location of powerpc git tree
From: Benjamin Herrenschmidt @ 2011-11-06 23:29 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Stephen Rothwell

Hi folks !

I've moved the powerpc git tree back to kernel.org. The URL should be
back to normal for users:

git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git

I've only uploaded the next and merge branches for now (merge is stale
btw, it's just there to avoid breaking scripts).

Note: Ignore the "linux-powerpc.git" tree that's next to that one, it's
a mistake and I haven't manage to delete it just yet...

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 2/4] powerpc/time: Use clocksource_register_hz
From: Paul Mackerras @ 2011-11-05  0:55 UTC (permalink / raw)
  To: John Stultz; +Cc: linuxppc-dev, Anton Blanchard
In-Reply-To: <1320326084.2892.4.camel@js-netbook>

On Thu, Nov 03, 2011 at 09:14:44AM -0400, John Stultz wrote:
> On Thu, 2011-11-03 at 11:59 +1100, Anton Blanchard wrote:
> > plain text document attachment (clock3)
> > Use clocksource_register_hz which calculates the shift/mult
> > factors for us.
> > 
> > Signed-off-by: Anton Blanchard <anton@samba.org>
> > ---
> > 
> > Index: linux-build/arch/powerpc/kernel/time.c
> > ===================================================================
> > --- linux-build.orig/arch/powerpc/kernel/time.c	2011-11-03 10:19:59.493679032 +1100
> > +++ linux-build/arch/powerpc/kernel/time.c	2011-11-03 10:20:00.965704053 +1100
> > @@ -86,8 +86,6 @@ static struct clocksource clocksource_rt
> >  	.rating       = 400,
> >  	.flags        = CLOCK_SOURCE_IS_CONTINUOUS,
> >  	.mask         = CLOCKSOURCE_MASK(64),
> > -	.shift        = 22,
> > -	.mult         = 0,	/* To be filled in */
> >  	.read         = rtc_read,
> >  };
> > 
> > @@ -97,8 +95,6 @@ static struct clocksource clocksource_ti
> >  	.rating       = 400,
> >  	.flags        = CLOCK_SOURCE_IS_CONTINUOUS,
> >  	.mask         = CLOCKSOURCE_MASK(64),
> > -	.shift        = 22,
> > -	.mult         = 0,	/* To be filled in */
> >  	.read         = timebase_read,
> >  };
> 
> So I've held off on ppc conversion to clocksource_register_hz due to the
> fact that the ppc vdso gettimeofday at least used to make assumptions
> that shift was 22.
> 
> Is that no longer the case?

It is still the case; specifically, update_vsyscall() in
arch/powerpc/kernel/time.c converts a multiplier value to a 'tb_to_xs'
multiplier (timebase to xsec conversion factor, where 1 xsec = 2^-20
seconds) using a factor which assumes a shift of 22.  The factor needs
to be 2^(20 + 64 - shift) / 1e9, so we could accommodate other shift
values by changing the line that computes new_tb_to_xs to do

       new_tb_to_xs = (u64) mult * (19342813113834067ULL >> shift);

assuming the shift value is easily available to update_vsyscall
(I assume it would be clock->shift).

Paul.

^ permalink raw reply

* Re: fpga driver on custom PPC target platform (P4080) ...
From: David Gibson @ 2011-11-05  0:40 UTC (permalink / raw)
  To: Robert Sciuk; +Cc: linuxppc-dev, devicetree-discuss, Tabi Timur-B04825
In-Reply-To: <2DD52030B5146141BEB762A11AE97C4C0100C8C1@SPQCEXC05.exfo.com>

On Fri, Nov 04, 2011 at 02:19:36PM -0400, Robert Sciuk wrote:
> > >
> > > I *believe* you are not supposed to create separate nodes for reading
> > > and writing.  I know that's how I2C works, but I think the I2C layer
> > > takes care of that for you.
> > >
> > > If you look at other device trees, you'll see they only have one node
> > > for any particular I2C device.
> > >
> > 
> > 
> > Thanks, Timur ... I've fixed the tree, and I'm tracking down the
> > problems with addressing the nodes ...
> 
> Ah,  my compatible attribute was wrong:
> 
> 	Compatible = "nxp,pca9539";
> 
> 	Should have been:
> 
> 	Compatible = "nxp,pca953x";
> 
> The tree now seems to bind the i2c gpio drivers properly ... on to
> the localbus mappings!

Ah.  In that case the drivers should probably be extended to recognize
the first compatible.  "wildcard" compatible strings are a bad idea,
unfortunately there are some already in the wild, as you've seen.  We
should try to phase them out though.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH 6/7] fsl_pmc: Add API to enable device as wakeup event source
From: Tabi Timur-B04825 @ 2011-11-05  0:08 UTC (permalink / raw)
  To: Zhao Chenhui-B35336
  Cc: netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	Li Yang-R58472
In-Reply-To: <1320410349-14600-1-git-send-email-chenhui.zhao@freescale.com>

On Fri, Nov 4, 2011 at 7:39 AM, Zhao Chenhui <chenhui.zhao@freescale.com> w=
rote:

> + =A0 =A0 =A0 if (!pmc_regs) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_WARNING "PMC is unavailable\n")=
;

Use pr_warn() and the other pr_xxx functions.

> + =A0 =A0 =A0 pmcdr_mask =3D (u32 *)of_get_property(clk_np, "fsl,pmcdr-ma=
sk", NULL);

The typecast is unnecessary here.

> + =A0 =A0 =A0 /* clear to enable clock in low power mode */
> + =A0 =A0 =A0 if (enable)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 clrbits32(&pmc_regs->pmcdr, *pmcdr_mask);
> + =A0 =A0 =A0 else
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 setbits32(&pmc_regs->pmcdr, *pmcdr_mask);

You need to use be32_to_cpup() when dereferencing a pointer to a
device tree property.

--=20
Timur Tabi
Linux kernel developer at Freescale=

^ permalink raw reply

* Re: [PATCH 3/7] powerpc/85xx: add sleep and deep sleep support
From: Felix Radensky @ 2011-11-04 22:43 UTC (permalink / raw)
  To: chenhui.zhao, linuxppc-dev, Felix Radensky
In-Reply-To: <1320410014-14453-1-git-send-email-chenhui.zhao@freescale.com>

[-- Attachment #1: Type: text/html, Size: 2208 bytes --]

^ permalink raw reply

* Re: [PATCH 6/7] fsl_pmc: Add API to enable device as wakeup event source
From: Scott Wood @ 2011-11-04 21:14 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: netdev, linuxppc-dev
In-Reply-To: <1320410349-14600-1-git-send-email-chenhui.zhao@freescale.com>

On 11/04/2011 07:39 AM, Zhao Chenhui wrote:
> @@ -45,6 +46,72 @@ static int has_lossless;
>   * code can be compatible with both 32-bit & 36-bit */
>  extern void mpc85xx_enter_deep_sleep(u64 ccsrbar, u32 powmgtreq);
>  
> +#ifdef CONFIG_FSL_PMC
> +/**
> + * pmc_enable_wake - enable OF device as wakeup event source
> + * @pdev: platform device affected
> + * @state: PM state from which device will issue wakeup events
> + * @enable: True to enable event generation; false to disable
> + *
> + * This enables the device as a wakeup event source, or disables it.
> + *
> + * RETURN VALUE:
> + * 0 is returned on success
> + * -EINVAL is returned if device is not supposed to wake up the system
> + * Error code depending on the platform is returned if both the platform and
> + * the native mechanism fail to enable the generation of wake-up events
> + */
> +int pmc_enable_wake(struct platform_device *pdev,
> +				suspend_state_t state, bool enable)

"pmc" is too generic for a global function.  If this can be either
enable or disable, perhaps it should be something like
mpc85xx_pmc_set_wake().

> +{
> +	int ret = 0;
> +	struct device_node *clk_np;
> +	u32 *pmcdr_mask;
> +
> +	if (!pmc_regs) {
> +		printk(KERN_WARNING "PMC is unavailable\n");
> +		return -ENOMEM;
> +	}

-ENOMEM is not appropriate here, maybe -ENODEV?

Should print __func__ so the user knows what's complaining.

> +	if (enable && !device_may_wakeup(&pdev->dev))
> +		return -EINVAL;
> +
> +	clk_np = of_parse_phandle(pdev->dev.of_node, "clk-handle", 0);
> +	if (!clk_np)
> +		return -EINVAL;
> +
> +	pmcdr_mask = (u32 *)of_get_property(clk_np, "fsl,pmcdr-mask", NULL);
> +	if (!pmcdr_mask) {
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	/* clear to enable clock in low power mode */
> +	if (enable)
> +		clrbits32(&pmc_regs->pmcdr, *pmcdr_mask);
> +	else
> +		setbits32(&pmc_regs->pmcdr, *pmcdr_mask);

We should probably initialize PMCDR to all bits set (or at least all
ones we know are valid) -- the default should be "not a wakeup source".

> +/**
> + * pmc_enable_lossless - enable lossless ethernet in low power mode
> + * @enable: True to enable event generation; false to disable
> + */
> +void pmc_enable_lossless(int enable)
> +{
> +	if (enable && has_lossless)
> +		setbits32(&pmc_regs->pmcsr, PMCSR_LOSSLESS);
> +	else
> +		clrbits32(&pmc_regs->pmcsr, PMCSR_LOSSLESS);
> +}
> +EXPORT_SYMBOL_GPL(pmc_enable_lossless);
> +#endif

Won't we overwrite this later?

-Scott

^ permalink raw reply

* Re: [PATCH 7/7] gianfar: add support for wake-on-packet
From: Scott Wood @ 2011-11-04 21:13 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: netdev, linuxppc-dev, afleming
In-Reply-To: <4EB45515.6060405@freescale.com>

On 11/04/2011 04:11 PM, Scott Wood wrote:
> On 11/04/2011 07:40 AM, Zhao Chenhui wrote:
>>  static int gfar_suspend(struct device *dev)
>>  {
>> @@ -1268,9 +1443,17 @@ static int gfar_suspend(struct device *dev)
>>  	struct gfar __iomem *regs = priv->gfargrp[0].regs;
>>  	unsigned long flags;
>>  	u32 tempval;
>> -
>>  	int magic_packet = priv->wol_en &&
>> -		(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
>> +		(priv->wol_opts & GIANFAR_WOL_MAGIC);
>> +	int arp_packet = priv->wol_en &&
>> +		(priv->wol_opts & GIANFAR_WOL_ARP);
>> +
>> +	if (arp_packet) {
>> +		pmc_enable_wake(priv->ofdev, PM_SUSPEND_MEM, 1);
>> +		pmc_enable_lossless(1);
>> +		gfar_arp_suspend(ndev);
>> +		return 0;
>> +	}
> 
> How do we know this isn't standby?

Or suspend to disk, for that matter?

-Scott

^ permalink raw reply

* Re: [PATCH 7/7] gianfar: add support for wake-on-packet
From: Scott Wood @ 2011-11-04 21:11 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: netdev, linuxppc-dev, afleming
In-Reply-To: <1320410403-14639-1-git-send-email-chenhui.zhao@freescale.com>

On 11/04/2011 07:40 AM, Zhao Chenhui wrote:
> diff --git a/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt b/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
> index 2c6be03..543e36c 100644
> --- a/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
> +++ b/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
> @@ -56,6 +56,9 @@ Properties:
>      hardware.
>    - fsl,magic-packet : If present, indicates that the hardware supports
>      waking up via magic packet.
> +  - fsl,wake-on-filer : If present, indicates that the hardware supports
> +    waking up via arp request to local ip address or unicast packet to
> +    local mac address.

Is there any way to determine this at runtime via the device's registers?

I think TSEC_ID2[TSEC_CFG] can be used.  The manual describes it
awkwardly, but it looks like 0x20 is the bit for the filer.

> @@ -751,7 +764,6 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
>  			FSL_GIANFAR_DEV_HAS_PADDING |
>  			FSL_GIANFAR_DEV_HAS_CSUM |
>  			FSL_GIANFAR_DEV_HAS_VLAN |
> -			FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
>  			FSL_GIANFAR_DEV_HAS_EXTENDED_HASH |
>  			FSL_GIANFAR_DEV_HAS_TIMER;

This is an unrelated change.  Are there any eTSECs that don't support
magic packet?

> +static int gfar_get_ip(struct net_device *dev)
> +{
> +	struct gfar_private *priv = netdev_priv(dev);
> +	struct in_device *in_dev = (struct in_device *)dev->ip_ptr;
> +	struct in_ifaddr *ifa;
> +
> +	if (in_dev != NULL) {
> +		ifa = (struct in_ifaddr *)in_dev->ifa_list;
> +		if (ifa != NULL) {
> +			memcpy(priv->ip_addr, &ifa->ifa_address, 4);
> +			return 0;
> +		}
> +	}
> +	return -ENOENT;
> +}

Unnecessary cast, ifa_list is already struct in_ifaddr *.

Better, use for_primary_ifa(), and document that you won't wake on ARP
packets for secondary IP addresses.

>  static int gfar_suspend(struct device *dev)
>  {
> @@ -1268,9 +1443,17 @@ static int gfar_suspend(struct device *dev)
>  	struct gfar __iomem *regs = priv->gfargrp[0].regs;
>  	unsigned long flags;
>  	u32 tempval;
> -
>  	int magic_packet = priv->wol_en &&
> -		(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
> +		(priv->wol_opts & GIANFAR_WOL_MAGIC);
> +	int arp_packet = priv->wol_en &&
> +		(priv->wol_opts & GIANFAR_WOL_ARP);
> +
> +	if (arp_packet) {
> +		pmc_enable_wake(priv->ofdev, PM_SUSPEND_MEM, 1);
> +		pmc_enable_lossless(1);
> +		gfar_arp_suspend(ndev);
> +		return 0;
> +	}

How do we know this isn't standby?

> @@ -577,11 +578,18 @@ static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
>  {
>  	struct gfar_private *priv = netdev_priv(dev);
>  
> +	wol->supported = 0;
> +	wol->wolopts = 0;
> +
>  	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) {
> -		wol->supported = WAKE_MAGIC;
> -		wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0;
> -	} else {
> -		wol->supported = wol->wolopts = 0;
> +		wol->supported |= WAKE_MAGIC;
> +		wol->wolopts |= (priv->wol_opts & GIANFAR_WOL_MAGIC) ?
> +							WAKE_MAGIC : 0;
> +	}
> +	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_ARP_PACKET) {
> +		wol->supported |= WAKE_ARP;
> +		wol->wolopts |= (priv->wol_opts & GIANFAR_WOL_ARP) ?
> +							WAKE_ARP : 0;
>  	}
>  }

Shouldn't we just make sure we don't set a bit in priv->wol_opts if we
don't support it?  Maybe create the "supported" mask at init time, so we
can use logical bit ops rather than a bunch of if statements?

> @@ -591,16 +599,21 @@ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
>  	unsigned long flags;
>  
>  	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
> -	    wol->wolopts != 0)
> -		return -EINVAL;
> -
> -	if (wol->wolopts & ~WAKE_MAGIC)
> +	    !(priv->device_flags & FSL_GIANFAR_DEV_HAS_ARP_PACKET))
>  		return -EINVAL;
>  
> -	device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC);
> -
>  	spin_lock_irqsave(&priv->bflock, flags);
> -	priv->wol_en =  !!device_may_wakeup(&dev->dev);
> +	if (wol->wolopts & WAKE_MAGIC) {
> +		priv->wol_en = 1;
> +		priv->wol_opts = GIANFAR_WOL_MAGIC;
> +	} else if (wol->wolopts & WAKE_ARP) {
> +		priv->wol_en = 1;
> +		priv->wol_opts = GIANFAR_WOL_ARP;

What if both WAKE_MAGIC and WAKE_ARP are set?

And shouldn't you make sure we actually support the one being requested,
rather than just making sure that we support one of the wake modes?

-Scott

^ permalink raw reply

* Re: [PATCH 5/7] fsl_pmc: update device bindings
From: Scott Wood @ 2011-11-04 20:19 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: linuxppc-dev
In-Reply-To: <4EB4456F.9020005@freescale.com>

On 11/04/2011 03:05 PM, Scott Wood wrote:
> On 11/04/2011 07:36 AM, Zhao Chenhui wrote:
>> +  "fsl,p1022-pmc" should be listed for any chip whose PMC is
>> +  compatible, and implies lossless Ethernet capability during sleep.
>>  
>>    "fsl,mpc8641d-pmc" should be listed for any chip whose PMC is
>>    compatible; all statements below that apply to "fsl,mpc8548-pmc" also
>>    apply to "fsl,mpc8641d-pmc".
>>  
>>    Compatibility does not include bit assignments in SCCR/PMCDR/DEVDISR; these
>> -  bit assignments are indicated via the sleep specifier in each device's
>> -  sleep property.
>> +  bit assignments are indicated via the clock nodes.  Device which has a
>> +  controllable clock source should have a "clk-handle" property pointing
>> +  to the clock node.
> 
> Do we have any code to use this?
> 
> Normally that shouldn't matter, but we already an unused binding for
> this. :-)
> 
> Please provide rationale for doing it this way.  Ideally it should
> probably use whatever http://devicetree.org/ClockBindings ends up being.

OK, I see the code now.  Still could use some explanation.

-Scott

^ permalink raw reply

* Re: [PATCH 5/7] fsl_pmc: update device bindings
From: Scott Wood @ 2011-11-04 20:05 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: linuxppc-dev
In-Reply-To: <1320410207-14537-1-git-send-email-chenhui.zhao@freescale.com>

On 11/04/2011 07:36 AM, Zhao Chenhui wrote:
> From: Li Yang <leoli@freescale.com>
> 
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
>  .../devicetree/bindings/powerpc/fsl/pmc.txt        |   63 +++++++++++--------
>  1 files changed, 36 insertions(+), 27 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt
> index 07256b7..d84b4f8 100644
> --- a/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt
> +++ b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt
> @@ -9,22 +9,27 @@ Properties:
>  
>    "fsl,mpc8548-pmc" should be listed for any chip whose PMC is
>    compatible.  "fsl,mpc8536-pmc" should also be listed for any chip
> -  whose PMC is compatible, and implies deep-sleep capability.
> +  whose PMC is compatible, and implies deep-sleep capability and
> +  wake on user defined packet(wakeup on ARP).

Why does the PMC care?  This is an ethernet controller feature, the PMC
is just keeping the wakeup-relevant parts of the ethernet controller
alive (whatever they happen to be).

Do we have any chips that have ethernet controller support for wake on
user-defined packet, but a sleep mode that doesn't let it be used?

BTW, please remove fsl,mpc8536-pmc from the p1023rds device tree -- it
was wrong before (no deep sleep, though it does appear to have jog
mode...), and is even more wrong with this provision (it has a different
ethernet controller).

> +  "fsl,p1022-pmc" should be listed for any chip whose PMC is
> +  compatible, and implies lossless Ethernet capability during sleep.
>  
>    "fsl,mpc8641d-pmc" should be listed for any chip whose PMC is
>    compatible; all statements below that apply to "fsl,mpc8548-pmc" also
>    apply to "fsl,mpc8641d-pmc".
>  
>    Compatibility does not include bit assignments in SCCR/PMCDR/DEVDISR; these
> -  bit assignments are indicated via the sleep specifier in each device's
> -  sleep property.
> +  bit assignments are indicated via the clock nodes.  Device which has a
> +  controllable clock source should have a "clk-handle" property pointing
> +  to the clock node.

Do we have any code to use this?

Normally that shouldn't matter, but we already an unused binding for
this. :-)

Please provide rationale for doing it this way.  Ideally it should
probably use whatever http://devicetree.org/ClockBindings ends up being.

>  - reg: For devices compatible with "fsl,mpc8349-pmc", the first resource
>    is the PMC block, and the second resource is the Clock Configuration
>    block.
>  
> -  For devices compatible with "fsl,mpc8548-pmc", the first resource
> -  is a 32-byte block beginning with DEVDISR.
> +  For devices compatible with "fsl,mpc8548-pmc", the second resource
> +  is a 32-byte block beginning with DEVDISR if supported.

Huh?

-Scott

^ permalink raw reply

* Re: [PATCH 4/7] powerpc/85xx: add support to JOG feature using cpufreq interface
From: Scott Wood @ 2011-11-04 19:42 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: Jerry Huang, linuxppc-dev
In-Reply-To: <1320410166-14500-1-git-send-email-chenhui.zhao@freescale.com>

On 11/04/2011 07:36 AM, Zhao Chenhui wrote:
> From: Li Yang <leoli@freescale.com>
> 
> Some 85xx silicons like MPC8536 and P1022 has the JOG PM feature.
> 
> The patch adds the support to change CPU frequency using the standard
> cpufreq interface. Add the all PLL ratio core support. The ratio CORE
> to CCB can 1:1, 1.5, 2:1, 2.5:1, 3:1, 3.5:1 and 4:1
> 
> Signed-off-by: Dave Liu <daveliu@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
> ---
>  arch/powerpc/platforms/85xx/Makefile  |    1 +
>  arch/powerpc/platforms/85xx/cpufreq.c |  255 +++++++++++++++++++++++++++++++++
>  arch/powerpc/platforms/Kconfig        |    8 +
>  3 files changed, 264 insertions(+), 0 deletions(-)
>  create mode 100644 arch/powerpc/platforms/85xx/cpufreq.c

Please name this something more specific, such as 85xx/cpufreq-jog.c

Other 85xx/qoriq chips, such as p4080, have different mechanisms for
updating CPU frequency.

> +static struct cpufreq_frequency_table mpc85xx_freqs[] = {
> +	{2,	0},
> +	{3,	0},
> +	{4,	0},
> +	{5,	0},
> +	{6,	0},
> +	{7,	0},
> +	{8,	0},
> +	{0,	CPUFREQ_TABLE_END},
> +};

Only p1022 can handle 1:1 (index 2).

> +static void set_pll(unsigned int pll, int cpu)
> +{
> +	int shift;
> +	u32 busfreq, corefreq, val;
> +	u32 core_spd, mask, tmp;
> +
> +	tmp = in_be32(guts + PMJCR);
> +	shift = (cpu == 1) ? CORE1_RATIO_SHIFT : CORE0_RATIO_SHIFT;
> +	busfreq = fsl_get_sys_freq();
> +	val = (pll & CORE_RATIO_MASK) << shift;
> +
> +	corefreq = ((busfreq * pll) >> 1);

Use "/ 2", not ">> 1".  Same asm code, more readable.

> +	/* must set the bit[18/19] if the requested core freq > 533 MHz */
> +	core_spd = (cpu == 1) ? PMJCR_CORE1_SPD_MASK : PMJCR_CORE0_SPD_MASK;
> +	if (corefreq > FREQ_533MHz)
> +		val |= core_spd;

this is the cutoff for p1022 -- on mpc8536 the manual says the cutoff is
800 MHz.

> +	mask = (cpu == 1) ? (PMJCR_CORE1_RATIO_MASK | PMJCR_CORE1_SPD_MASK) :
> +		(PMJCR_CORE0_RATIO_MASK | PMJCR_CORE0_SPD_MASK);
> +	tmp &= ~mask;
> +	tmp |= val;
> +	out_be32(guts + PMJCR, tmp);

clrsetbits_be32()

> +	val = in_be32(guts + PMJCR);
> +	out_be32(guts + POWMGTCSR,
> +			POWMGTCSR_LOSSLESS_MASK | POWMGTCSR_JOG_MASK);

setbits32()

> +	pr_debug("PMJCR request %08x at CPU %d\n", tmp, cpu);
> +}
> +
> +static void verify_pll(int cpu)
> +{
> +	int shift;
> +	u32 busfreq, pll, corefreq;
> +
> +	shift = (cpu == 1) ? CORE1_RATIO_SHIFT : CORE0_RATIO_SHIFT;
> +	busfreq = fsl_get_sys_freq();
> +	pll = (in_be32(guts + PORPLLSR) >> shift) & CORE_RATIO_MASK;
> +
> +	corefreq = (busfreq * pll) >> 1;
> +	corefreq /= 1000000;
> +	pr_debug("PORPLLSR core freq %dMHz at CPU %d\n", corefreq, cpu);
> +}

It looks like the entire point of this function is to make a debug
print...  #ifdef DEBUG the contents?  Or if we mark fsl_get_sys_freq()
as __pure (or better, read this once at init, since it involves
searching the device tree), will it all get optimized away?


> +	/* initialize frequency table */
> +	pr_info("core %d frequency table:\n", policy->cpu);
> +	for (i = 0; mpc85xx_freqs[i].frequency != CPUFREQ_TABLE_END; i++) {
> +		mpc85xx_freqs[i].frequency =
> +				(busfreq * mpc85xx_freqs[i].index) >> 1;
> +		pr_info("%d: %dkHz\n", i, mpc85xx_freqs[i].frequency);
> +	}

This should be pr_debug.

> +	/* the latency of a transition, the unit is ns */
> +	policy->cpuinfo.transition_latency = 2000;
> +
> +	cur_pll = get_pll(policy->cpu);
> +	pr_debug("current pll is at %d\n", cur_pll);
> +
> +	for (i = 0; mpc85xx_freqs[i].frequency != CPUFREQ_TABLE_END; i++) {
> +		if (mpc85xx_freqs[i].index == cur_pll)
> +			policy->cur = mpc85xx_freqs[i].frequency;
> +	}

You could combine these loops.

> +	/* this ensures that policy->cpuinfo_min
> +	 * and policy->cpuinfo_max are set correctly */

comment style

> +static int mpc85xx_cpufreq_target(struct cpufreq_policy *policy,
> +			      unsigned int target_freq,
> +			      unsigned int relation)
> +{
> +	struct cpufreq_freqs freqs;
> +	unsigned int new;
> +
> +	cpufreq_frequency_table_target(policy,
> +				       mpc85xx_freqs,
> +				       target_freq,
> +				       relation,
> +				       &new);
> +
> +	freqs.old = policy->cur;
> +	freqs.new = mpc85xx_freqs[new].frequency;
> +	freqs.cpu = policy->cpu;
> +
> +	mutex_lock(&mpc85xx_switch_mutex);
> +	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
> +
> +	pr_info("Setting frequency for core %d to %d kHz, " \
> +		 "PLL ratio is %d/2\n",
> +		 policy->cpu,
> +		 mpc85xx_freqs[new].frequency,
> +		 mpc85xx_freqs[new].index);
> +
> +	set_pll(mpc85xx_freqs[new].index, policy->cpu);
> +
> +	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
> +	mutex_unlock(&mpc85xx_switch_mutex);
> +
> +	ppc_proc_freq = freqs.new * 1000ul;

ppc_proc_freq is global -- can CPUs not have their frequencies adjusted
separately?

It should be under the lock, if the lock is needed at all.

> +/*
> + * module init and destoy
> + */
> +static struct of_device_id mpc85xx_jog_ids[] __initdata = {
> +	{ .compatible = "fsl,mpc8536-guts", },
> +	{ .compatible = "fsl,p1022-guts", },
> +	{}
> +};
> +
> +static int __init mpc85xx_cpufreq_init(void)
> +{
> +	struct device_node *np;
> +
> +	pr_info("Freescale MPC85xx CPU frequency switching driver\n");

If you're going to print something here, print it after you find a node
you can work with -- not on all 85xx/qoriq that have this driver enabled.

-Scott

^ permalink raw reply

* Re: [PATCH 1/7] powerpc/85xx: re-enable timebase sync disabled by KEXEC patch
From: Scott Wood @ 2011-11-04 19:38 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, Zhao Chenhui
In-Reply-To: <51CCC521-0A2C-4940-98F0-BA0075D6F122@kernel.crashing.org>

On 11/04/2011 02:33 PM, Kumar Gala wrote:
> 
> On Nov 4, 2011, at 12:33 PM, Scott Wood wrote:
> 
>> On 11/04/2011 07:29 AM, Zhao Chenhui wrote:
>>> From: Li Yang <leoli@freescale.com>
>>>
>>> The timebase sync is not only necessary when using KEXEC. It should also
>>> be used by normal boot up and cpu hotplug. Remove the ifdef added by
>>> the KEXEC patch.
>>
>> The KEXEC patch didn't just add the ifdef, it also added the initializers:
>>
>>> @@ -105,8 +107,64 @@ smp_85xx_setup_cpu(int cpu_nr)
>>>
>>> struct smp_ops_t smp_85xx_ops = {
>>>        .kick_cpu = smp_85xx_kick_cpu,
>>> +#ifdef CONFIG_KEXEC
>>> +       .give_timebase  = smp_generic_give_timebase,
>>> +       .take_timebase  = smp_generic_take_timebase,
>>> +#endif
>>> };
>>
>> U-Boot synchronizes the timebase on 85xx.  With what chip and U-Boot
>> version are you seeing this not happen?
>>
>> If you are seeing only a small (around one tick) difference, make sure
>> you're running a U-Boot that has this commit:
[snip]
> 
> Scott,
> 
> Aren't we going to need this when a core is woken back up w/o any state?

We'll need some form of timebase resync if a core is individually
hard-reset -- I was responding to the "should also be used by normal
boot up" bit.

For kexec/hotplug, if we must reset the core (for deep sleep we must),
any reason not to do the sync the same way U-Boot does?

-Scott

^ permalink raw reply

* Re: [PATCH 1/7] powerpc/85xx: re-enable timebase sync disabled by KEXEC patch
From: Kumar Gala @ 2011-11-04 19:33 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, Zhao Chenhui
In-Reply-To: <4EB421FD.6010805@freescale.com>


On Nov 4, 2011, at 12:33 PM, Scott Wood wrote:

> On 11/04/2011 07:29 AM, Zhao Chenhui wrote:
>> From: Li Yang <leoli@freescale.com>
>> 
>> The timebase sync is not only necessary when using KEXEC. It should also
>> be used by normal boot up and cpu hotplug. Remove the ifdef added by
>> the KEXEC patch.
> 
> The KEXEC patch didn't just add the ifdef, it also added the initializers:
> 
>> @@ -105,8 +107,64 @@ smp_85xx_setup_cpu(int cpu_nr)
>> 
>> struct smp_ops_t smp_85xx_ops = {
>>        .kick_cpu = smp_85xx_kick_cpu,
>> +#ifdef CONFIG_KEXEC
>> +       .give_timebase  = smp_generic_give_timebase,
>> +       .take_timebase  = smp_generic_take_timebase,
>> +#endif
>> };
> 
> U-Boot synchronizes the timebase on 85xx.  With what chip and U-Boot
> version are you seeing this not happen?
> 
> If you are seeing only a small (around one tick) difference, make sure
> you're running a U-Boot that has this commit:
> 
>> commit 7afc45ad7d9493208d89072cbb78a5bfc8034b59
>> Author: Kumar Gala <galak@kernel.crashing.org>
>> Date:   Sun Mar 13 10:55:53 2011 -0500
>> 
>>    powerpc/85xx: Fix synchronization of timebase on MP boot
>> 
>>    There is a small ordering issue in the master core in that we need to
>>    make sure the disabling of the timebase in the SoC is visible before we
>>    set the value to 0.  We can simply just read back the value to
>>    synchronizatize the write, before we set TB to 0.
>> 
>>    Reported-by: Dan Hettena
>>    Tested-by: Dan Hettena
>>    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>

Scott,

Aren't we going to need this when a core is woken back up w/o any state?

- k

^ permalink raw reply

* Re: [PATCH 3/7] powerpc/85xx: add sleep and deep sleep support
From: Scott Wood @ 2011-11-04 18:45 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: linuxppc-dev
In-Reply-To: <1320410014-14453-1-git-send-email-chenhui.zhao@freescale.com>

On 11/04/2011 07:33 AM, Zhao Chenhui wrote:
> +/* Cast the ccsrbar to 64-bit parameter so that the assembly
> + * code can be compatible with both 32-bit & 36-bit */
> +extern void mpc85xx_enter_deep_sleep(u64 ccsrbar, u32 powmgtreq);

/*
 * Please use proper
 * Linux multi-line comment format.
 */

>  static int pmc_suspend_enter(suspend_state_t state)
>  {
>  	int ret;
> +	u32 powmgtreq = 0x00500000;

Where does this 0x00500000 come from?  Please symbolically define
individual bits.

The comment in the asm code says it should be 0x00100000, BTW.

> +
> +	switch (state) {
> +	case PM_SUSPEND_MEM:
> +#ifdef CONFIG_SPE
> +		enable_kernel_spe();
> +#endif

Should comment that currently only e500v2 hardware supports deep sleep
-- else we'd need to save normal FP here.

> +		pr_debug("Entering deep sleep\n");
> +
> +		local_irq_disable();
> +		mpc85xx_enter_deep_sleep(get_immrbase(),
> +				powmgtreq);
> +		pr_debug("Resumed from deep sleep\n");
> +
> +		return 0;
> +
> +	/* else fall-through */
> +	case PM_SUSPEND_STANDBY:

What fall-through?  You just returned.

> +	}
>  
> -	/* Upon resume, wait for SLP bit to be clear. */
> -	ret = spin_event_timeout((in_be32(&pmc_regs->pmcsr) & PMCSR_SLP) == 0,
> -				 10000, 10) ? 0 : -ETIMEDOUT;
> -	if (ret)
> -		dev_err(pmc_dev, "tired waiting for SLP bit to clear\n");
> -	return ret;
>  }

Remove that blank line as well.

> @@ -58,13 +101,23 @@ static const struct platform_suspend_ops pmc_suspend_ops = {
>  	.enter = pmc_suspend_enter,
>  };
>  
> -static int pmc_probe(struct platform_device *ofdev)
> +static int pmc_probe(struct platform_device *pdev)
>  {
> -	pmc_regs = of_iomap(ofdev->dev.of_node, 0);
> +	struct device_node *np = pdev->dev.of_node;
> +
> +	pmc_regs = of_iomap(pdev->dev.of_node, 0);
>  	if (!pmc_regs)
>  		return -ENOMEM;
>  
> -	pmc_dev = &ofdev->dev;
> +	has_deep_sleep = 0;
> +	if (of_device_is_compatible(np, "fsl,mpc8536-pmc"))
> +		has_deep_sleep = 1;
> +
> +	has_lossless = 0;
> +	if (of_device_is_compatible(np, "fsl,p1022-pmc"))
> +		has_lossless = 1;
> +

You never use has_lossless.

-Scott

^ permalink raw reply

* Re: [PATCH 2/7] powerpc/85xx: add HOTPLUG_CPU support
From: Scott Wood @ 2011-11-04 18:35 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: linuxppc-dev
In-Reply-To: <1320409889-14408-1-git-send-email-chenhui.zhao@freescale.com>

On 11/04/2011 07:31 AM, Zhao Chenhui wrote:
> From: Li Yang <leoli@freescale.com>
> 
> Add support to disable and re-enable individual cores at runtime
> on MPC85xx/QorIQ SMP machines. Currently support e500 core.
> 
> MPC85xx machines use ePAPR spin-table in boot page for CPU kick-off.
> This patch uses the boot page from bootloader to boot core at runtime.
> It supports 32-bit and 36-bit physical address.

Note that there is no guarantee that the bootloader can handle you
resetting a core.  In ePAPR the spin table is a one-time release
mechanism, not a core reset mechanism.  If this has a U-Boot dependency,
document that.

>  #ifdef CONFIG_SMP
>  /* When we get here, r24 needs to hold the CPU # */
>  	.globl __secondary_start
> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> index 7bf2187..12a54f0 100644
> --- a/arch/powerpc/kernel/smp.c
> +++ b/arch/powerpc/kernel/smp.c
> @@ -381,8 +381,14 @@ void generic_cpu_die(unsigned int cpu)
>  
>  	for (i = 0; i < 100; i++) {
>  		smp_rmb();
> -		if (per_cpu(cpu_state, cpu) == CPU_DEAD)
> +		if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
> +			/*
> +			 * After another core sets cpu_state to CPU_DEAD,
> +			 * it needs some time to die.
> +			 */
> +			msleep(10);
>  			return;
> +		}
>  		msleep(100);

It would be better to do this as a call into platform-specific code than
can check registers to determine whether the core has checked out (in
our case, whether it has entered nap) -- or to do a suitable delay for
that platform if this isn't possible.

> diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
> index 9b0de9c..5a54fc1 100644
> --- a/arch/powerpc/platforms/85xx/smp.c
> +++ b/arch/powerpc/platforms/85xx/smp.c
> @@ -17,6 +17,7 @@
>  #include <linux/of.h>
>  #include <linux/kexec.h>
>  #include <linux/highmem.h>
> +#include <linux/cpu.h>
>  
>  #include <asm/machdep.h>
>  #include <asm/pgtable.h>
> @@ -30,26 +31,141 @@
>  
>  extern void __early_start(void);
>  
> -#define BOOT_ENTRY_ADDR_UPPER	0
> -#define BOOT_ENTRY_ADDR_LOWER	1
> -#define BOOT_ENTRY_R3_UPPER	2
> -#define BOOT_ENTRY_R3_LOWER	3
> -#define BOOT_ENTRY_RESV		4
> -#define BOOT_ENTRY_PIR		5
> -#define BOOT_ENTRY_R6_UPPER	6
> -#define BOOT_ENTRY_R6_LOWER	7
> -#define NUM_BOOT_ENTRY		8
> -#define SIZE_BOOT_ENTRY		(NUM_BOOT_ENTRY * sizeof(u32))
> -
> -static int __init
> -smp_85xx_kick_cpu(int nr)
> +#define MPC85xx_BPTR_OFF		0x00020
> +#define MPC85xx_BPTR_EN			0x80000000
> +#define MPC85xx_BPTR_BOOT_PAGE_MASK	0x00ffffff
> +#define MPC85xx_BRR_OFF			0xe0e4
> +#define MPC85xx_ECM_EEBPCR_OFF		0x01010
> +#define MPC85xx_PIC_PIR_OFF		0x41090
> +
> +struct epapr_entry {

ePAPR is more than just the spin table.  Call it something like
epapr_spin_table.

> +	u32	addr_h;
> +	u32	addr_l;
> +	u32	r3_h;
> +	u32	r3_l;
> +	u32	reserved;
> +	u32	pir;
> +	u32	r6_h;
> +	u32	r6_l;
> +};

Get rid of r6, it is not part of the ePAPR spin table.

> +static int is_corenet;
> +static void __cpuinit smp_85xx_setup_cpu(int cpu_nr);
> +
> +#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)

Why PPC32?

> +extern void flush_disable_L1(void);

If this isn't already in a header file, put it in one.

> +static void __cpuinit smp_85xx_mach_cpu_die(void)
> +{
> +	unsigned int cpu = smp_processor_id();
> +	register u32 tmp;
> +
> +	local_irq_disable();
> +	idle_task_exit();
> +	generic_set_cpu_dead(cpu);
> +	smp_wmb();
> +
> +	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
> +	mtspr(SPRN_TCR, 0);

If clearing TSR matters at all (I'm not sure that it does), first clear
TCR, then TSR.

> +	flush_disable_L1();

You'll also need to take down L2 on e500mc.

> +	tmp = 0;
> +	if (cpu_has_feature(CPU_FTR_CAN_NAP))
> +		tmp = HID0_NAP;
> +	else if (cpu_has_feature(CPU_FTR_CAN_DOZE))
> +		tmp = HID0_DOZE;

Those FTR bits are for what we can do in idle, and can be cleared if the
user sets CONFIG_BDI_SWITCH.

On 85xx we always want to nap here, and at least on e500mc it seems to
be mandatory.  From the p5020 RM description of PIR:

> For proper system operation, a core should be reset in this way only if the core is already in nap or sleep
> state. Because a core in either state cannot perform the necessary write to cause a hard reset, a core cannot
> put itself into hard reset.

Note that on e500mc we don't use HID0/MSR_WE to enter nap, we need to
hit the CCSR register.  And unless you can somehow guarantee that only
one core at a time is doing this, we'll need some oher core to actually
place us in nap (since once we enter nap we're not running so can't
release a lock).

> +	if (tmp) {
> +		tmp |= mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_NAP|HID0_SLEEP);
> +
> +		smp_mb();

smp_mb()?  This is always SMP...  It looks like you meant some specific
sync instruction as part of an architected sequence, so just use that.

> +		isync();
> +		mtspr(SPRN_HID0, tmp);
> +		isync();
> +
> +		tmp = mfmsr();
> +		tmp |= MSR_WE;
> +		smp_mb();
> +		mtmsr(tmp);
> +		isync();
> +	}
> +
> +	for (;;);
> +}
> +
> +static void __cpuinit smp_85xx_reset_core(int nr)
> +{
> +	__iomem u32 *vaddr, *pir_vaddr;
> +	u32 val, cpu_mask;
> +
> +	/* If CoreNet platform, use BRR as release register. */
> +	if (is_corenet) {
> +		cpu_mask = 1 << nr;
> +		vaddr = ioremap(get_immrbase() + MPC85xx_BRR_OFF, 4);
> +	} else {
> +		cpu_mask = 1 << (24 + nr);
> +		vaddr = ioremap(get_immrbase() + MPC85xx_ECM_EEBPCR_OFF, 4);
> +	}

Please use the device tree node, not get_immrbase().

> +	val = in_be32(vaddr);
> +	if (!(val & cpu_mask)) {
> +		out_be32(vaddr, val | cpu_mask);
> +	} else {
> +		/* reset core */
> +		pir_vaddr = ioremap(get_immrbase() + MPC85xx_PIC_PIR_OFF, 4);
> +		val = in_be32(pir_vaddr);
> +		/* reset assert */
> +		val |= (1 << nr);
> +		out_be32(pir_vaddr, val);

Use setbits32().

> +		val = in_be32(pir_vaddr);
> +		val &= ~(1 << nr);
> +		/* reset negate */
> +		out_be32(pir_vaddr, val);

clrbits32().

Is there any amount of time we need to keep the reset pin asserted?

> +		iounmap(pir_vaddr);
> +	}
> +	iounmap(vaddr);
> +}
> +
> +static int __cpuinit smp_85xx_map_bootpg(u32 page)
> +{
> +	__iomem u32 *bootpg_ptr;
> +	u32 bptr;
> +
> +	/* Get the BPTR */
> +	bootpg_ptr = ioremap(get_immrbase() + MPC85xx_BPTR_OFF, 4);
> +
> +	/* Set the BPTR to the secondary boot page */
> +	bptr = MPC85xx_BPTR_EN | (page & MPC85xx_BPTR_BOOT_PAGE_MASK);
> +	out_be32(bootpg_ptr, bptr);
> +
> +	iounmap(bootpg_ptr);
> +	return 0;
> +}

Shouldn't the boot page already be set by U-Boot?

> +static int __cpuinit smp_85xx_kick_cpu(int nr)
>  {
>  	unsigned long flags;
>  	const u64 *cpu_rel_addr;
> -	__iomem u32 *bptr_vaddr;
> +	__iomem struct epapr_entry *epapr;
>  	struct device_node *np;
> -	int n = 0;
> +	int n = 0, hw_cpu = get_hard_smp_processor_id(nr);
>  	int ioremappable;
> +	int ret = 0;
>  
>  	WARN_ON (nr < 0 || nr >= NR_CPUS);
>  
> @@ -73,46 +189,79 @@ smp_85xx_kick_cpu(int nr)
>  
>  	/* Map the spin table */
>  	if (ioremappable)
> -		bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
> +		epapr = ioremap(*cpu_rel_addr, sizeof(struct epapr_entry));
>  	else
> -		bptr_vaddr = phys_to_virt(*cpu_rel_addr);
> +		epapr = phys_to_virt(*cpu_rel_addr);
>  
>  	local_irq_save(flags);
>  
> -	out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr);
> +	out_be32(&epapr->pir, hw_cpu);
>  #ifdef CONFIG_PPC32
> -	out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
> +#ifdef CONFIG_HOTPLUG_CPU
> +	if (system_state == SYSTEM_RUNNING) {
> +		out_be32(&epapr->addr_l, 0);
> +		smp_85xx_map_bootpg((u32)(*cpu_rel_addr >> PAGE_SHIFT));

Why is this inside PPC32?

> +		smp_85xx_reset_core(hw_cpu);
> +
> +		/* wait until core is ready... */
> +		n = 0;
> +		while ((in_be32(&epapr->addr_l) != 1) && (++n < 1000))
> +			udelay(100);
> +		if (n > 1000) {

if (n == 1000)

or

if (in_be32(&epapr->addr_l) != 1)

> +			pr_err("timeout waiting for core%d to reset\n",	nr);
> +			ret = -ENOENT;
> +			goto out;
> +		}
> +		/*  clear the acknowledge status */
> +		__secondary_hold_acknowledge = -1;
> +
> +		smp_85xx_unmap_bootpg();
> +	}
> +#endif
> +	out_be32(&epapr->addr_l, __pa(__early_start));
>  
>  	if (!ioremappable)
> -		flush_dcache_range((ulong)bptr_vaddr,
> -				(ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
> +		flush_dcache_range((ulong)epapr,
> +				(ulong)epapr + sizeof(struct epapr_entry));
>  
>  	/* Wait a bit for the CPU to ack. */
> -	while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
> +	n = 0;
> +	while ((__secondary_hold_acknowledge != hw_cpu) && (++n < 1000))
>  		mdelay(1);
> +	if (n > 1000) {

if (n == 1000)

or

if (__secondary_hold_acknowledge != hw_cpu)

> +		pr_err("timeout waiting for core%d to ack\n", nr);

pr_err("%s: timeout waiting for core %d to ack\n", __func__, nr);

Likewise elsewhere.  Maybe also/instead mention hw_cpu.

> +		ret = -ENOENT;
> +		goto out;
> +	}
> +out:
>  #else
>  	smp_generic_kick_cpu(nr);
>  
> -	out_be64((u64 *)(bptr_vaddr + BOOT_ENTRY_ADDR_UPPER),
> +	out_be64((u64 *)(&epapr->addr_h),
>  		__pa((u64)*((unsigned long long *) generic_secondary_smp_init)));
>  
>  	if (!ioremappable)
> -		flush_dcache_range((ulong)bptr_vaddr,
> -				(ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
> +		flush_dcache_range((ulong)epapr,
> +				(ulong)epapr + sizeof(struct epapr_entry));

We don't wait for the core to come up on 64-bit?

> @@ -228,14 +376,18 @@ void __init mpc85xx_smp_init(void)
>  {
>  	struct device_node *np;
>  
> -	smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu;
> -
>  	np = of_find_node_by_type(NULL, "open-pic");
>  	if (np) {
>  		smp_85xx_ops.probe = smp_mpic_probe;
>  		smp_85xx_ops.message_pass = smp_mpic_message_pass;
>  	}
>  
> +	/* Check if the chip is based on CoreNet platform. */
> +	is_corenet = 0;
> +	np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-device-config-1.0");
> +	if (np)
> +		is_corenet = 1;

Please also check for the non-corenet guts node.  If you don't find
either, disable the mechanism -- you're probably running under a hypervisor.

-Scott

^ permalink raw reply

* RE: fpga driver on custom PPC target platform (P4080) ...
From: Robert Sciuk @ 2011-11-04 18:19 UTC (permalink / raw)
  To: Robert Sciuk, Tabi Timur-B04825; +Cc: devicetree-discuss, linuxppc-dev
In-Reply-To: <CAOZdJXWjS4t9cOKRB3rxy0iCFAYRyEgg6kfQwvydUQSyO1ttoA@mail.gmail.com>

> >
> > I *believe* you are not supposed to create separate nodes for =
reading
> > and writing.  I know that's how I2C works, but I think the I2C layer
> > takes care of that for you.
> >
> > If you look at other device trees, you'll see they only have one =
node
> > for any particular I2C device.
> >
> > --
> > Timur Tabi
> > Linux kernel developer at Freescale
>=20
>=20
> Thanks, Timur ... I've fixed the tree, and I'm tracking down the
> problems with addressing the nodes ...

Ah,  my compatible attribute was wrong:

	Compatible =3D "nxp,pca9539";

	Should have been:

	Compatible =3D "nxp,pca953x";

The tree now seems to bind the i2c gpio drivers properly ... on to the =
localbus mappings!

Rob.

^ permalink raw reply

* Re: [PATCH 3/7] powerpc/85xx: add sleep and deep sleep support
From: Felix Radensky @ 2011-11-04 17:36 UTC (permalink / raw)
  To: chenhui.zhao, linuxppc-dev
In-Reply-To: <1320410014-14453-1-git-send-email-chenhui.zhao@freescale.com>

[-- Attachment #1: Type: text/html, Size: 2181 bytes --]

^ permalink raw reply

* Re: [PATCH 1/7] powerpc/85xx: re-enable timebase sync disabled by KEXEC patch
From: Scott Wood @ 2011-11-04 17:33 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: linuxppc-dev
In-Reply-To: <1320409787-14360-1-git-send-email-chenhui.zhao@freescale.com>

On 11/04/2011 07:29 AM, Zhao Chenhui wrote:
> From: Li Yang <leoli@freescale.com>
> 
> The timebase sync is not only necessary when using KEXEC. It should also
> be used by normal boot up and cpu hotplug. Remove the ifdef added by
> the KEXEC patch.

The KEXEC patch didn't just add the ifdef, it also added the initializers:

> @@ -105,8 +107,64 @@ smp_85xx_setup_cpu(int cpu_nr)
>  
>  struct smp_ops_t smp_85xx_ops = {
>         .kick_cpu = smp_85xx_kick_cpu,
> +#ifdef CONFIG_KEXEC
> +       .give_timebase  = smp_generic_give_timebase,
> +       .take_timebase  = smp_generic_take_timebase,
> +#endif
>  };

U-Boot synchronizes the timebase on 85xx.  With what chip and U-Boot
version are you seeing this not happen?

If you are seeing only a small (around one tick) difference, make sure
you're running a U-Boot that has this commit:

> commit 7afc45ad7d9493208d89072cbb78a5bfc8034b59
> Author: Kumar Gala <galak@kernel.crashing.org>
> Date:   Sun Mar 13 10:55:53 2011 -0500
> 
>     powerpc/85xx: Fix synchronization of timebase on MP boot
>     
>     There is a small ordering issue in the master core in that we need to
>     make sure the disabling of the timebase in the SoC is visible before we
>     set the value to 0.  We can simply just read back the value to
>     synchronizatize the write, before we set TB to 0.
>     
>     Reported-by: Dan Hettena
>     Tested-by: Dan Hettena
>     Signed-off-by: Kumar Gala <galak@kernel.crashing.org>


-Scott

^ permalink raw reply

* RE: fpga driver on custom PPC target platform (P4080) ...
From: Robert Sciuk @ 2011-11-04 16:42 UTC (permalink / raw)
  To: Tabi Timur-B04825; +Cc: devicetree-discuss, linuxppc-dev
In-Reply-To: <CAOZdJXWjS4t9cOKRB3rxy0iCFAYRyEgg6kfQwvydUQSyO1ttoA@mail.gmail.com>



> > It appears that I'm not correctly creating the pca9539 nodes as of
> yet (I'll be adding the phandles shortly). =A0Any pointers for pca9539
> driver nodes would be appreciated, as I took these from a similar =
tree,
> but not the 95xx driver. =A0I'll match them up with the code in the
> morning ...
>=20
> I *believe* you are not supposed to create separate nodes for reading
> and writing.  I know that's how I2C works, but I think the I2C layer
> takes care of that for you.
>=20
> If you look at other device trees, you'll see they only have one node
> for any particular I2C device.
>=20
> --
> Timur Tabi
> Linux kernel developer at Freescale


Thanks, Timur ... I've fixed the tree, and I'm tracking down the =
problems with addressing the nodes ...

^ permalink raw reply

* Re: fpga driver on custom PPC target platform (P4080) ...
From: Tabi Timur-B04825 @ 2011-11-04 16:36 UTC (permalink / raw)
  To: Robert Sciuk
  Cc: devicetree-discuss@lists.ozlabs.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <2DD52030B5146141BEB762A11AE97C4C0100C735@SPQCEXC05.exfo.com>

On Thu, Nov 3, 2011 at 5:12 PM, Robert Sciuk <robert.sciuk@exfo.com> wrote:

> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lim_r: gpio@e8 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0compatible=
 =3D "nxp,pca9539";
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0reg =3D <0=
xe8>;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0#gpio-cell=
s =3D <2>;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0gpio-contr=
oller;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0polarity =
=3D <0x00>;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0};
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lim_w: gpio@e9 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0compatible=
 =3D "nxp,pca9539";
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0reg =3D <0=
xe9>;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0#gpio-cell=
s =3D <2>;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0gpio-contr=
oller;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0polarity =
=3D <0x00>;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0};
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0};
>
> It appears that I'm not correctly creating the pca9539 nodes as of yet (I=
'll be adding the phandles shortly). =A0Any pointers for pca9539 driver nod=
es would be appreciated, as I took these from a similar tree, but not the 9=
5xx driver. =A0I'll match them up with the code in the morning ...

I *believe* you are not supposed to create separate nodes for reading
and writing.  I know that's how I2C works, but I think the I2C layer
takes care of that for you.

If you look at other device trees, you'll see they only have one node
for any particular I2C device.

--=20
Timur Tabi
Linux kernel developer at Freescale=

^ permalink raw reply

* Re: Support for multiple MSI interrupts on MPC8377
From: Matthew Wilcox @ 2011-11-04 14:00 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Giffel, Brad
In-Reply-To: <1320292282.3852.33.camel@concordia>

On Thu, Nov 03, 2011 at 02:51:22PM +1100, Michael Ellerman wrote:
> There is some code in place to support multiple MSI, but only in the
> generic code (drivers/pci/msi.c), and I'm not sure if it's complete.
> There is no arch support, for any arch AFAIK, and certainly not for
> powerpc.

I think there's an ARM or MIPS architecture that implements support for
it ... the x86 support was never merged.

-- 
Matthew Wilcox				Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

^ permalink raw reply

* [PATCH 7/7] gianfar: add support for wake-on-packet
From: Zhao Chenhui @ 2011-11-04 12:40 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: netdev, afleming

On certain chip like MPC8536 and P1022, system can be waked up from
sleep by user defined packet. This patch implements that system waked
up by ARP request packet or unicast patcket to this station.

When entering suspend state, the gianfar driver sets receive queue
filer table to filter all of packets except ARP request packet and
unicast patcket to this station. The driver temporarily uses the last
receive queue to receive the user defined packet.

In suspend state, the receive part of eTSEC keeps working. When
receiving a user defined packet, it generates an interrupt to
wake up the system.

The rule of the filer table is as below.
  if (arp request to local ip address)
      accept it to the last queue
  elif (unicast packet to local mac address)
      accept it to the last queue
  else
      reject it
  endif
Note: The local ip/mac address is the ethernet ip/mac address of
the station.

Here is an example of enabling and testing wake up on user defined packet.
  ifconfig eth0 10.193.20.169
  ethtool -s eth0 wol a
  echo standby > /sys/power/state or echo mem > /sys/power/state

Ping from PC host to wake up the station:
  ping 10.193.20.169

Signed-off-by: Dave Liu <daveliu@freescale.com>
Signed-off-by: Jin Qing <b24347@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
Acked-by: Andy Fleming <afleming@freescale.com>
---
 .../devicetree/bindings/net/fsl-tsec-phy.txt       |    3 +
 drivers/net/ethernet/freescale/gianfar.c           |  320 +++++++++++++++++++-
 drivers/net/ethernet/freescale/gianfar.h           |   33 ++-
 drivers/net/ethernet/freescale/gianfar_ethtool.c   |   35 ++-
 4 files changed, 366 insertions(+), 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt b/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
index 2c6be03..543e36c 100644
--- a/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
+++ b/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
@@ -56,6 +56,9 @@ Properties:
     hardware.
   - fsl,magic-packet : If present, indicates that the hardware supports
     waking up via magic packet.
+  - fsl,wake-on-filer : If present, indicates that the hardware supports
+    waking up via arp request to local ip address or unicast packet to
+    local mac address.
   - bd-stash : If present, indicates that the hardware supports stashing
     buffer descriptors in the L2.
   - rx-stash-len : Denotes the number of bytes of a received buffer to stash
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 83199fd..a159251 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -85,6 +85,8 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/in.h>
+#include <linux/inetdevice.h>
+#include <sysdev/fsl_soc.h>
 #include <linux/net_tstamp.h>
 
 #include <asm/io.h>
@@ -147,6 +149,17 @@ static void gfar_clear_exact_match(struct net_device *dev);
 static void gfar_set_mac_for_addr(struct net_device *dev, int num,
 				  const u8 *addr);
 static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp);
+
+#ifdef CONFIG_PM
+static void gfar_halt_rx(struct net_device *dev);
+static void gfar_rx_start(struct net_device *dev);
+static void gfar_enable_filer(struct net_device *dev);
+static void gfar_disable_filer(struct net_device *dev);
+static void gfar_config_filer_arptable(struct net_device *dev);
+static void gfar_restore_filer_table(struct net_device *dev);
+static int gfar_get_ip(struct net_device *dev);
+#endif
 
 MODULE_AUTHOR("Freescale Semiconductor, Inc");
 MODULE_DESCRIPTION("Gianfar Ethernet Driver");
@@ -751,7 +764,6 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
 			FSL_GIANFAR_DEV_HAS_PADDING |
 			FSL_GIANFAR_DEV_HAS_CSUM |
 			FSL_GIANFAR_DEV_HAS_VLAN |
-			FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
 			FSL_GIANFAR_DEV_HAS_EXTENDED_HASH |
 			FSL_GIANFAR_DEV_HAS_TIMER;
 
@@ -766,6 +778,9 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
 	if (of_get_property(np, "fsl,magic-packet", NULL))
 		priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
 
+	if (of_get_property(np, "fsl,wake-on-filer", NULL))
+		priv->device_flags |= FSL_GIANFAR_DEV_HAS_ARP_PACKET;
+
 	priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
 
 	/* Find the TBI PHY.  If it's not there, we don't support SGMII */
@@ -1168,8 +1183,11 @@ static int gfar_probe(struct platform_device *ofdev)
 		goto register_fail;
 	}
 
-	device_init_wakeup(&dev->dev,
-		priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+	if ((priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) ||
+	    (priv->device_flags & FSL_GIANFAR_DEV_HAS_ARP_PACKET)) {
+		device_set_wakeup_capable(&ofdev->dev, true);
+		device_set_wakeup_enable(&ofdev->dev, false);
+	}
 
 	/* fill out IRQ number and name fields */
 	len_devname = strlen(dev->name);
@@ -1260,6 +1278,163 @@ static int gfar_remove(struct platform_device *ofdev)
 }
 
 #ifdef CONFIG_PM
+static void gfar_enable_filer(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
+	u32 temp;
+
+	lock_rx_qs(priv);
+
+	temp = gfar_read(&regs->rctrl);
+	temp &= ~(RCTRL_FSQEN | RCTRL_PRSDEP_MASK);
+	temp |= RCTRL_FILREN | RCTRL_PRSDEP_L2L3;
+	gfar_write(&regs->rctrl, temp);
+
+	unlock_rx_qs(priv);
+}
+
+static void gfar_disable_filer(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
+	u32 temp;
+
+	lock_rx_qs(priv);
+
+	temp = gfar_read(&regs->rctrl);
+	temp &= ~RCTRL_FILREN;
+	gfar_write(&regs->rctrl, temp);
+
+	unlock_rx_qs(priv);
+}
+
+static int gfar_get_ip(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	struct in_device *in_dev = (struct in_device *)dev->ip_ptr;
+	struct in_ifaddr *ifa;
+
+	if (in_dev != NULL) {
+		ifa = (struct in_ifaddr *)in_dev->ifa_list;
+		if (ifa != NULL) {
+			memcpy(priv->ip_addr, &ifa->ifa_address, 4);
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
+static void gfar_restore_filer_table(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	u32 rqfcr, rqfpr;
+	int i;
+
+	lock_rx_qs(priv);
+
+	for (i = 0; i <= MAX_FILER_IDX; i++) {
+		rqfcr = priv->ftp_rqfcr[i];
+		rqfpr = priv->ftp_rqfpr[i];
+		gfar_write_filer(priv, i, rqfcr, rqfpr);
+	}
+
+	unlock_rx_qs(priv);
+}
+
+static void gfar_config_filer_arptable(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	u8 *ip_addr;
+	u32 wakeup_ip, dest_mac_addr_h, dest_mac_addr_l;
+	u32 rqfpr = 0x0;
+	u32 rqfcr = RQFCR_RJE | RQFCR_CMP_MATCH;
+	u8  rqfcr_queue = priv->num_rx_queues - 1;
+	int i;
+
+	if (gfar_get_ip(dev))
+		netif_err(priv, wol, dev, "WOL: get the ip address error\n");
+	ip_addr = priv->ip_addr;
+
+	wakeup_ip = (*ip_addr << 24) | (*(ip_addr + 1) << 16) | \
+		    (*(ip_addr + 2) << 8) | (*(ip_addr + 3));
+
+	dest_mac_addr_h = (dev->dev_addr[0] << 16) | \
+			  (dev->dev_addr[1] << 8) | dev->dev_addr[2];
+	dest_mac_addr_l = (dev->dev_addr[3] << 16) | \
+			  (dev->dev_addr[4] << 8) | dev->dev_addr[5];
+
+	lock_rx_qs(priv);
+
+	for (i = 0; i <= MAX_FILER_IDX; i++)
+		gfar_write_filer(priv, i, rqfcr, rqfpr);
+
+	/* ARP request filer, filling the packet to queue #1 */
+	rqfcr = (rqfcr_queue << 10) | RQFCR_AND |
+				RQFCR_CMP_EXACT | RQFCR_PID_MASK;
+	rqfpr = RQFPR_ARQ;
+	gfar_write_filer(priv, 0, rqfcr, rqfpr);
+
+	rqfcr = (rqfcr_queue << 10) | RQFCR_AND |
+				RQFCR_CMP_EXACT | RQFCR_PID_PARSE;
+	rqfpr = RQFPR_ARQ;
+	gfar_write_filer(priv, 1, rqfcr, rqfpr);
+
+	/* DEST_IP address in ARP packet, filling it to queue #1 */
+	rqfcr = (rqfcr_queue << 10) | RQFCR_AND |
+				RQFCR_CMP_EXACT | RQFCR_PID_MASK;
+	rqfpr = FPR_FILER_MASK;
+	gfar_write_filer(priv, 2, rqfcr, rqfpr);
+
+	rqfcr = RQFCR_GPI | (rqfcr_queue << 10) |
+				RQFCR_CMP_EXACT | RQFCR_PID_DIA;
+	rqfpr = wakeup_ip;
+	gfar_write_filer(priv, 3, rqfcr, rqfpr);
+
+	/* Unicast packet, filling it to queue #1 */
+	rqfcr = (rqfcr_queue << 10) | RQFCR_AND |
+				RQFCR_CMP_EXACT | RQFCR_PID_DAH;
+	rqfpr = dest_mac_addr_h;
+	gfar_write_filer(priv, 4, rqfcr, rqfpr);
+
+	rqfcr = RQFCR_GPI | (rqfcr_queue << 10) |
+				RQFCR_CMP_EXACT | RQFCR_PID_DAL;
+	mb();
+	rqfpr = dest_mac_addr_l;
+	gfar_write_filer(priv, 5, rqfcr, rqfpr);
+
+	unlock_rx_qs(priv);
+}
+
+static int gfar_arp_suspend(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	netif_device_detach(dev);
+
+	if (netif_running(dev)) {
+		local_irq_save(flags);
+		lock_tx_qs(priv);
+		lock_rx_qs(priv);
+
+		gfar_halt(dev);
+
+		unlock_rx_qs(priv);
+		unlock_tx_qs(priv);
+		local_irq_restore(flags);
+
+		disable_napi(priv);
+
+		gfar_disable_filer(dev);
+		gfar_config_filer_arptable(dev);
+		gfar_enable_filer(dev);
+		gfar_rx_start(dev);
+	}
+
+	return 0;
+}
+
 
 static int gfar_suspend(struct device *dev)
 {
@@ -1268,9 +1443,17 @@ static int gfar_suspend(struct device *dev)
 	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	unsigned long flags;
 	u32 tempval;
-
 	int magic_packet = priv->wol_en &&
-		(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+		(priv->wol_opts & GIANFAR_WOL_MAGIC);
+	int arp_packet = priv->wol_en &&
+		(priv->wol_opts & GIANFAR_WOL_ARP);
+
+	if (arp_packet) {
+		pmc_enable_wake(priv->ofdev, PM_SUSPEND_MEM, 1);
+		pmc_enable_lossless(1);
+		gfar_arp_suspend(ndev);
+		return 0;
+	}
 
 	netif_device_detach(ndev);
 
@@ -1299,6 +1482,7 @@ static int gfar_suspend(struct device *dev)
 		disable_napi(priv);
 
 		if (magic_packet) {
+			pmc_enable_wake(priv->ofdev, PM_SUSPEND_MEM, 1);
 			/* Enable interrupt on Magic Packet */
 			gfar_write(&regs->imask, IMASK_MAG);
 
@@ -1314,6 +1498,30 @@ static int gfar_suspend(struct device *dev)
 	return 0;
 }
 
+static int gfar_arp_resume(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	int i;
+
+	if (!netif_running(dev)) {
+		netif_device_attach(dev);
+		return 0;
+	}
+
+	gfar_halt_rx(dev);
+	gfar_disable_filer(dev);
+	gfar_restore_filer_table(dev);
+	gfar_start(dev);
+
+	netif_device_attach(dev);
+	enable_napi(priv);
+
+	for (i = 0; i < priv->num_grps; i++)
+		gfar_schedule_cleanup(&priv->gfargrp[i]);
+
+	return 0;
+}
+
 static int gfar_resume(struct device *dev)
 {
 	struct gfar_private *priv = dev_get_drvdata(dev);
@@ -1322,7 +1530,18 @@ static int gfar_resume(struct device *dev)
 	unsigned long flags;
 	u32 tempval;
 	int magic_packet = priv->wol_en &&
-		(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+		(priv->wol_opts & GIANFAR_WOL_MAGIC);
+	int arp_packet = priv->wol_en &&
+		(priv->wol_opts & GIANFAR_WOL_ARP);
+
+	if (arp_packet) {
+		pmc_enable_wake(priv->ofdev, PM_SUSPEND_MEM, 0);
+		pmc_enable_lossless(0);
+		gfar_arp_resume(ndev);
+		return 0;
+	} else if (magic_packet) {
+		pmc_enable_wake(priv->ofdev, PM_SUSPEND_MEM, 0);
+	}
 
 	if (!netif_running(ndev)) {
 		netif_device_attach(ndev);
@@ -1602,6 +1821,48 @@ static int __gfar_is_rx_idle(struct gfar_private *priv)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+/* Halt the receive queues */
+static void gfar_halt_rx(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
+	u32 tempval;
+	int i = 0;
+
+	for (i = 0; i < priv->num_grps; i++) {
+		regs = priv->gfargrp[i].regs;
+		/* Mask all interrupts */
+		gfar_write(&regs->imask, IMASK_INIT_CLEAR);
+
+		/* Clear all interrupts */
+		gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
+	}
+
+	regs = priv->gfargrp[0].regs;
+	/* Stop the DMA, and wait for it to stop */
+	tempval = gfar_read(&regs->dmactrl);
+	if ((tempval & DMACTRL_GRS) != DMACTRL_GRS) {
+		int ret;
+
+		tempval |= DMACTRL_GRS;
+		gfar_write(&regs->dmactrl, tempval);
+
+		do {
+			ret = spin_event_timeout(((gfar_read(&regs->ievent) &
+				IEVENT_GRSC) == IEVENT_GRSC), 1000000, 0);
+			if (!ret && !(gfar_read(&regs->ievent) & IEVENT_GRSC))
+				ret = __gfar_is_rx_idle(priv);
+		} while (!ret);
+	}
+
+	/* Disable Rx in MACCFG1  */
+	tempval = gfar_read(&regs->maccfg1);
+	tempval &= ~MACCFG1_RX_EN;
+	gfar_write(&regs->maccfg1, tempval);
+}
+#endif
+
 /* Halt the receive and transmit queues */
 static void gfar_halt_nodisable(struct net_device *dev)
 {
@@ -1808,6 +2069,40 @@ void gfar_start(struct net_device *dev)
 	dev->trans_start = jiffies; /* prevent tx timeout */
 }
 
+#ifdef CONFIG_PM
+void gfar_rx_start(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
+	u32 tempval;
+	int i = 0;
+
+	/* Enable Rx in MACCFG1 */
+	tempval = gfar_read(&regs->maccfg1);
+	tempval |= MACCFG1_RX_EN;
+	gfar_write(&regs->maccfg1, tempval);
+
+	/* Initialize DMACTRL to have WWR and WOP */
+	tempval = gfar_read(&regs->dmactrl);
+	tempval |= DMACTRL_INIT_SETTINGS;
+	gfar_write(&regs->dmactrl, tempval);
+
+	/* Make sure we aren't stopped */
+	tempval = gfar_read(&regs->dmactrl);
+	tempval &= ~DMACTRL_GRS;
+	gfar_write(&regs->dmactrl, tempval);
+
+	for (i = 0; i < priv->num_grps; i++) {
+		regs = priv->gfargrp[i].regs;
+		/* Clear RHLT, so that the DMA starts polling now */
+		gfar_write(&regs->rstat, priv->gfargrp[i].rstat);
+
+		/* Unmask the interrupts we look for */
+		gfar_write(&regs->imask, IMASK_DEFAULT);
+	}
+}
+#endif
+
 void gfar_configure_coalescing(struct gfar_private *priv,
 	unsigned long tx_mask, unsigned long rx_mask)
 {
@@ -1970,7 +2265,7 @@ static int gfar_enet_open(struct net_device *dev)
 
 	netif_tx_start_all_queues(dev);
 
-	device_set_wakeup_enable(&dev->dev, priv->wol_en);
+	device_set_wakeup_enable(&priv->ofdev->dev, priv->wol_en);
 
 	return err;
 }
@@ -2657,6 +2952,17 @@ static inline void count_errors(unsigned short status, struct net_device *dev)
 
 irqreturn_t gfar_receive(int irq, void *grp_id)
 {
+	struct gfar_priv_grp *gfargrp = grp_id;
+	struct gfar __iomem *regs = gfargrp->regs;
+	u32 ievent;
+
+	ievent = gfar_read(&regs->ievent);
+
+	if ((ievent & IEVENT_FGPI) == IEVENT_FGPI) {
+		gfar_write(&regs->ievent, ievent & IEVENT_RX_MASK);
+		return IRQ_HANDLED;
+	}
+
 	gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id);
 	return IRQ_HANDLED;
 }
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
index 9aa4377..efa6478 100644
--- a/drivers/net/ethernet/freescale/gianfar.h
+++ b/drivers/net/ethernet/freescale/gianfar.h
@@ -232,6 +232,14 @@ extern const char gfar_driver_version[];
 #define RQUEUE_EN7		0x00000001
 #define RQUEUE_EN_ALL		0x000000FF
 
+/* Wake-On-Lan options */
+#define GIANFAR_WOL_PHY		(1 << 0)
+#define GIANFAR_WOL_UCAST	(1 << 1)
+#define GIANFAR_WOL_MCAST	(1 << 2)
+#define GIANFAR_WOL_BCAST	(1 << 3)
+#define GIANFAR_WOL_ARP		(1 << 4)
+#define GIANFAR_WOL_MAGIC	(1 << 5)
+
 /* Init to do tx snooping for buffers and descriptors */
 #define DMACTRL_INIT_SETTINGS   0x000000c3
 #define DMACTRL_GRS             0x00000010
@@ -277,11 +285,15 @@ extern const char gfar_driver_version[];
 #define RCTRL_PAL_MASK		0x001f0000
 #define RCTRL_VLEX		0x00002000
 #define RCTRL_FILREN		0x00001000
+#define RCTRL_FSQEN		0x00000800
 #define RCTRL_GHTX		0x00000400
 #define RCTRL_IPCSEN		0x00000200
 #define RCTRL_TUCSEN		0x00000100
 #define RCTRL_PRSDEP_MASK	0x000000c0
 #define RCTRL_PRSDEP_INIT	0x000000c0
+#define RCTRL_PRSDEP_L2		0x00000040
+#define RCTRL_PRSDEP_L2L3	0x00000080
+#define RCTRL_PRSDEP_L2L3L4	0x000000c0
 #define RCTRL_PRSFM		0x00000020
 #define RCTRL_PROM		0x00000008
 #define RCTRL_EMEN		0x00000002
@@ -327,18 +339,20 @@ extern const char gfar_driver_version[];
 #define IEVENT_MAG		0x00000800
 #define IEVENT_GRSC		0x00000100
 #define IEVENT_RXF0		0x00000080
+#define IEVENT_FGPI		0x00000010
 #define IEVENT_FIR		0x00000008
 #define IEVENT_FIQ		0x00000004
 #define IEVENT_DPE		0x00000002
 #define IEVENT_PERR		0x00000001
-#define IEVENT_RX_MASK          (IEVENT_RXB0 | IEVENT_RXF0 | IEVENT_BSY)
+#define IEVENT_RX_MASK          (IEVENT_RXB0 | IEVENT_RXF0 | \
+					IEVENT_FGPI | IEVENT_BSY)
 #define IEVENT_TX_MASK          (IEVENT_TXB | IEVENT_TXF)
 #define IEVENT_RTX_MASK         (IEVENT_RX_MASK | IEVENT_TX_MASK)
 #define IEVENT_ERR_MASK         \
-(IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
- IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \
- | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \
- | IEVENT_MAG | IEVENT_BABR)
+	(IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
+	 IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC | \
+	 IEVENT_CRL | IEVENT_XFUN | IEVENT_FIR | IEVENT_FIQ | \
+	 IEVENT_DPE | IEVENT_PERR | IEVENT_MAG | IEVENT_BABR)
 
 #define IMASK_INIT_CLEAR	0x00000000
 #define IMASK_BABR              0x80000000
@@ -359,14 +373,15 @@ extern const char gfar_driver_version[];
 #define IMASK_MAG		0x00000800
 #define IMASK_GRSC              0x00000100
 #define IMASK_RXFEN0		0x00000080
+#define IMASK_FGPI		0x00000010
 #define IMASK_FIR		0x00000008
 #define IMASK_FIQ		0x00000004
 #define IMASK_DPE		0x00000002
 #define IMASK_PERR		0x00000001
 #define IMASK_DEFAULT  (IMASK_TXEEN | IMASK_TXFEN | IMASK_TXBEN | \
 		IMASK_RXFEN0 | IMASK_BSY | IMASK_EBERR | IMASK_BABR | \
-		IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
-		| IMASK_PERR)
+		IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_FGPI | \
+		IMASK_FIR | IMASK_FIQ | IMASK_DPE | IMASK_PERR)
 #define IMASK_RTX_DISABLED ((~(IMASK_RXFEN0 | IMASK_TXFEN | IMASK_BSY)) \
 			   & IMASK_DEFAULT)
 
@@ -883,6 +898,7 @@ struct gfar {
 #define FSL_GIANFAR_DEV_HAS_BD_STASHING		0x00000200
 #define FSL_GIANFAR_DEV_HAS_BUF_STASHING	0x00000400
 #define FSL_GIANFAR_DEV_HAS_TIMER		0x00000800
+#define FSL_GIANFAR_DEV_HAS_ARP_PACKET		0x00001000
 
 #if (MAXGROUPS == 2)
 #define DEFAULT_MAPPING 	0xAA
@@ -1115,6 +1131,9 @@ struct gfar_private {
 
 	struct work_struct reset_task;
 
+	u8 ip_addr[4];
+	int wol_opts;
+
 	/* Network Statistics */
 	struct gfar_extra_stats extra_stats;
 
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index 212736b..336c419 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -29,6 +29,7 @@
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -577,11 +578,18 @@ static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct gfar_private *priv = netdev_priv(dev);
 
+	wol->supported = 0;
+	wol->wolopts = 0;
+
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) {
-		wol->supported = WAKE_MAGIC;
-		wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0;
-	} else {
-		wol->supported = wol->wolopts = 0;
+		wol->supported |= WAKE_MAGIC;
+		wol->wolopts |= (priv->wol_opts & GIANFAR_WOL_MAGIC) ?
+							WAKE_MAGIC : 0;
+	}
+	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_ARP_PACKET) {
+		wol->supported |= WAKE_ARP;
+		wol->wolopts |= (priv->wol_opts & GIANFAR_WOL_ARP) ?
+							WAKE_ARP : 0;
 	}
 }
 
@@ -591,16 +599,21 @@ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 	unsigned long flags;
 
 	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
-	    wol->wolopts != 0)
-		return -EINVAL;
-
-	if (wol->wolopts & ~WAKE_MAGIC)
+	    !(priv->device_flags & FSL_GIANFAR_DEV_HAS_ARP_PACKET))
 		return -EINVAL;
 
-	device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC);
-
 	spin_lock_irqsave(&priv->bflock, flags);
-	priv->wol_en =  !!device_may_wakeup(&dev->dev);
+	if (wol->wolopts & WAKE_MAGIC) {
+		priv->wol_en = 1;
+		priv->wol_opts = GIANFAR_WOL_MAGIC;
+	} else if (wol->wolopts & WAKE_ARP) {
+		priv->wol_en = 1;
+		priv->wol_opts = GIANFAR_WOL_ARP;
+	} else {
+		priv->wol_en = 0;
+		priv->wol_opts = 0;
+	}
+	device_set_wakeup_enable(&priv->ofdev->dev, (u32)priv->wol_en);
 	spin_unlock_irqrestore(&priv->bflock, flags);
 
 	return 0;
-- 
1.6.4.1

^ permalink raw reply related

* [PATCH 6/7] fsl_pmc: Add API to enable device as wakeup event source
From: Zhao Chenhui @ 2011-11-04 12:39 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: netdev

Add APIs for setting wakeup source and lossless Ethernet in low power modes.
These APIs can be used by wake-on-packet feature.

Signed-off-by: Dave Liu <daveliu@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Jin Qing <b24347@freescale.com>
Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
---
 arch/powerpc/sysdev/fsl_pmc.c |   67 +++++++++++++++++++++++++++++++++++++++++
 arch/powerpc/sysdev/fsl_soc.h |   11 +++++++
 2 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c
index 58d35d8..dab8161 100644
--- a/arch/powerpc/sysdev/fsl_pmc.c
+++ b/arch/powerpc/sysdev/fsl_pmc.c
@@ -38,6 +38,7 @@ static struct device *pmc_dev;
 static struct pmc_regs __iomem *pmc_regs;
 
 #define PMCSR_SLP	0x00020000
+#define PMCSR_LOSSLESS	0x00400000
 static int has_deep_sleep;
 static int has_lossless;
 
@@ -45,6 +46,72 @@ static int has_lossless;
  * code can be compatible with both 32-bit & 36-bit */
 extern void mpc85xx_enter_deep_sleep(u64 ccsrbar, u32 powmgtreq);
 
+#ifdef CONFIG_FSL_PMC
+/**
+ * pmc_enable_wake - enable OF device as wakeup event source
+ * @pdev: platform device affected
+ * @state: PM state from which device will issue wakeup events
+ * @enable: True to enable event generation; false to disable
+ *
+ * This enables the device as a wakeup event source, or disables it.
+ *
+ * RETURN VALUE:
+ * 0 is returned on success
+ * -EINVAL is returned if device is not supposed to wake up the system
+ * Error code depending on the platform is returned if both the platform and
+ * the native mechanism fail to enable the generation of wake-up events
+ */
+int pmc_enable_wake(struct platform_device *pdev,
+				suspend_state_t state, bool enable)
+{
+	int ret = 0;
+	struct device_node *clk_np;
+	u32 *pmcdr_mask;
+
+	if (!pmc_regs) {
+		printk(KERN_WARNING "PMC is unavailable\n");
+		return -ENOMEM;
+	}
+
+	if (enable && !device_may_wakeup(&pdev->dev))
+		return -EINVAL;
+
+	clk_np = of_parse_phandle(pdev->dev.of_node, "clk-handle", 0);
+	if (!clk_np)
+		return -EINVAL;
+
+	pmcdr_mask = (u32 *)of_get_property(clk_np, "fsl,pmcdr-mask", NULL);
+	if (!pmcdr_mask) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* clear to enable clock in low power mode */
+	if (enable)
+		clrbits32(&pmc_regs->pmcdr, *pmcdr_mask);
+	else
+		setbits32(&pmc_regs->pmcdr, *pmcdr_mask);
+
+out:
+	of_node_put(clk_np);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pmc_enable_wake);
+
+/**
+ * pmc_enable_lossless - enable lossless ethernet in low power mode
+ * @enable: True to enable event generation; false to disable
+ */
+void pmc_enable_lossless(int enable)
+{
+	if (enable && has_lossless)
+		setbits32(&pmc_regs->pmcsr, PMCSR_LOSSLESS);
+	else
+		clrbits32(&pmc_regs->pmcsr, PMCSR_LOSSLESS);
+}
+EXPORT_SYMBOL_GPL(pmc_enable_lossless);
+#endif
+
 static int pmc_suspend_enter(suspend_state_t state)
 {
 	int ret;
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index c6d0073..f4f322a 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -3,6 +3,8 @@
 #ifdef __KERNEL__
 
 #include <asm/mmu.h>
+#include <linux/platform_device.h>
+#include <linux/suspend.h>
 
 struct spi_device;
 
@@ -21,6 +23,15 @@ struct device_node;
 
 extern void fsl_rstcr_restart(char *cmd);
 
+#ifdef CONFIG_FSL_PMC
+int pmc_enable_wake(struct platform_device *pdev, suspend_state_t state,
+		bool enable);
+void pmc_enable_lossless(int enable);
+#else
+#define pmc_enable_wake(pdev, state, enable)
+#define pmc_enable_lossless(enable)
+#endif
+
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
 
 /* The different ports that the DIU can be connected to */
-- 
1.6.4.1

^ permalink raw reply related

* [PATCH 4/7] powerpc/85xx: add support to JOG feature using cpufreq interface
From: Zhao Chenhui @ 2011-11-04 12:36 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jerry Huang, Zhao Chenhui

From: Li Yang <leoli@freescale.com>

Some 85xx silicons like MPC8536 and P1022 has the JOG PM feature.

The patch adds the support to change CPU frequency using the standard
cpufreq interface. Add the all PLL ratio core support. The ratio CORE
to CCB can 1:1, 1.5, 2:1, 2.5:1, 3:1, 3.5:1 and 4:1

Signed-off-by: Dave Liu <daveliu@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
---
 arch/powerpc/platforms/85xx/Makefile  |    1 +
 arch/powerpc/platforms/85xx/cpufreq.c |  255 +++++++++++++++++++++++++++++++++
 arch/powerpc/platforms/Kconfig        |    8 +
 3 files changed, 264 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/platforms/85xx/cpufreq.c

diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 0bdaddc..75432a5 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -3,6 +3,7 @@
 #
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_SUSPEND)	+= sleep.o
+obj-$(CONFIG_MPC85xx_CPUFREQ) += cpufreq.o
 
 obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
 obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
diff --git a/arch/powerpc/platforms/85xx/cpufreq.c b/arch/powerpc/platforms/85xx/cpufreq.c
new file mode 100644
index 0000000..20f0458
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/cpufreq.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
+ *	Dave Liu <daveliu@freescale.com>
+ *
+ * The cpufreq driver is for Freescale 85xx processor,
+ * based on arch/powerpc/platforms/cell/cbe_cpufreq.c
+ * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007
+ *	Christian Krafft <krafft@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/cpufreq.h>
+#include <linux/of_platform.h>
+
+#include <asm/prom.h>
+#include <asm/time.h>
+#include <asm/reg.h>
+#include <asm/io.h>
+
+#include <sysdev/fsl_soc.h>
+
+static DEFINE_MUTEX(mpc85xx_switch_mutex);
+static void __iomem *guts;
+
+static struct cpufreq_frequency_table mpc85xx_freqs[] = {
+	{2,	0},
+	{3,	0},
+	{4,	0},
+	{5,	0},
+	{6,	0},
+	{7,	0},
+	{8,	0},
+	{0,	CPUFREQ_TABLE_END},
+};
+
+#define FREQ_533MHz	533340000
+#define CORE0_RATIO_SHIFT	16
+#define CORE1_RATIO_SHIFT	24
+#define CORE_RATIO_MASK		0x3f
+
+#define PORPLLSR	0x0
+
+#define PMJCR		0x7c
+#define PMJCR_CORE0_SPD_MASK	0x00001000
+#define PMJCR_CORE1_SPD_MASK	0x00002000
+#define PMJCR_CORE0_RATIO_MASK	(CORE_RATIO_MASK << CORE0_RATIO_SHIFT)
+#define PMJCR_CORE1_RATIO_MASK	(CORE_RATIO_MASK << CORE1_RATIO_SHIFT)
+
+#define POWMGTCSR	0x80
+#define POWMGTCSR_LOSSLESS_MASK	0x00400000
+#define POWMGTCSR_JOG_MASK	0x00200000
+
+/*
+ * hardware specific functions
+ */
+static int get_pll(int cpu)
+{
+	int ret, shift;
+	u32 pll = in_be32(guts + PORPLLSR);
+	shift = (cpu == 1) ? CORE1_RATIO_SHIFT : CORE0_RATIO_SHIFT;
+	ret = (pll >> shift) & CORE_RATIO_MASK;
+
+	return ret;
+}
+
+static void set_pll(unsigned int pll, int cpu)
+{
+	int shift;
+	u32 busfreq, corefreq, val;
+	u32 core_spd, mask, tmp;
+
+	tmp = in_be32(guts + PMJCR);
+	shift = (cpu == 1) ? CORE1_RATIO_SHIFT : CORE0_RATIO_SHIFT;
+	busfreq = fsl_get_sys_freq();
+	val = (pll & CORE_RATIO_MASK) << shift;
+
+	corefreq = ((busfreq * pll) >> 1);
+	/* must set the bit[18/19] if the requested core freq > 533 MHz */
+	core_spd = (cpu == 1) ? PMJCR_CORE1_SPD_MASK : PMJCR_CORE0_SPD_MASK;
+	if (corefreq > FREQ_533MHz)
+		val |= core_spd;
+
+	mask = (cpu == 1) ? (PMJCR_CORE1_RATIO_MASK | PMJCR_CORE1_SPD_MASK) :
+		(PMJCR_CORE0_RATIO_MASK | PMJCR_CORE0_SPD_MASK);
+	tmp &= ~mask;
+	tmp |= val;
+	out_be32(guts + PMJCR, tmp);
+	val = in_be32(guts + PMJCR);
+	out_be32(guts + POWMGTCSR,
+			POWMGTCSR_LOSSLESS_MASK | POWMGTCSR_JOG_MASK);
+	pr_debug("PMJCR request %08x at CPU %d\n", tmp, cpu);
+}
+
+static void verify_pll(int cpu)
+{
+	int shift;
+	u32 busfreq, pll, corefreq;
+
+	shift = (cpu == 1) ? CORE1_RATIO_SHIFT : CORE0_RATIO_SHIFT;
+	busfreq = fsl_get_sys_freq();
+	pll = (in_be32(guts + PORPLLSR) >> shift) & CORE_RATIO_MASK;
+
+	corefreq = (busfreq * pll) >> 1;
+	corefreq /= 1000000;
+	pr_debug("PORPLLSR core freq %dMHz at CPU %d\n", corefreq, cpu);
+}
+
+/*
+ * cpufreq functions
+ */
+static int mpc85xx_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+	u32 busfreq = fsl_get_sys_freq();
+	int i, cur_pll;
+
+	/* we need the freq unit with kHz */
+	busfreq /= 1000;
+
+	/* initialize frequency table */
+	pr_info("core %d frequency table:\n", policy->cpu);
+	for (i = 0; mpc85xx_freqs[i].frequency != CPUFREQ_TABLE_END; i++) {
+		mpc85xx_freqs[i].frequency =
+				(busfreq * mpc85xx_freqs[i].index) >> 1;
+		pr_info("%d: %dkHz\n", i, mpc85xx_freqs[i].frequency);
+	}
+
+	/* the latency of a transition, the unit is ns */
+	policy->cpuinfo.transition_latency = 2000;
+
+	cur_pll = get_pll(policy->cpu);
+	pr_debug("current pll is at %d\n", cur_pll);
+
+	for (i = 0; mpc85xx_freqs[i].frequency != CPUFREQ_TABLE_END; i++) {
+		if (mpc85xx_freqs[i].index == cur_pll)
+			policy->cur = mpc85xx_freqs[i].frequency;
+	}
+	pr_debug("current core freq is %d\n", policy->cur);
+
+	cpufreq_frequency_table_get_attr(mpc85xx_freqs, policy->cpu);
+
+	/* this ensures that policy->cpuinfo_min
+	 * and policy->cpuinfo_max are set correctly */
+	return cpufreq_frequency_table_cpuinfo(policy, mpc85xx_freqs);
+}
+
+static int mpc85xx_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+static int mpc85xx_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, mpc85xx_freqs);
+}
+
+static int mpc85xx_cpufreq_target(struct cpufreq_policy *policy,
+			      unsigned int target_freq,
+			      unsigned int relation)
+{
+	struct cpufreq_freqs freqs;
+	unsigned int new;
+
+	cpufreq_frequency_table_target(policy,
+				       mpc85xx_freqs,
+				       target_freq,
+				       relation,
+				       &new);
+
+	freqs.old = policy->cur;
+	freqs.new = mpc85xx_freqs[new].frequency;
+	freqs.cpu = policy->cpu;
+
+	mutex_lock(&mpc85xx_switch_mutex);
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	pr_info("Setting frequency for core %d to %d kHz, " \
+		 "PLL ratio is %d/2\n",
+		 policy->cpu,
+		 mpc85xx_freqs[new].frequency,
+		 mpc85xx_freqs[new].index);
+
+	set_pll(mpc85xx_freqs[new].index, policy->cpu);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	mutex_unlock(&mpc85xx_switch_mutex);
+
+	ppc_proc_freq = freqs.new * 1000ul;
+
+	verify_pll(policy->cpu);
+
+	return 0;
+}
+
+static struct cpufreq_driver mpc85xx_cpufreq_driver = {
+	.verify		= mpc85xx_cpufreq_verify,
+	.target		= mpc85xx_cpufreq_target,
+	.init		= mpc85xx_cpufreq_cpu_init,
+	.exit		= mpc85xx_cpufreq_cpu_exit,
+	.name		= "mpc85xx-cpufreq",
+	.owner		= THIS_MODULE,
+	.flags		= CPUFREQ_CONST_LOOPS,
+};
+
+/*
+ * module init and destoy
+ */
+static struct of_device_id mpc85xx_jog_ids[] __initdata = {
+	{ .compatible = "fsl,mpc8536-guts", },
+	{ .compatible = "fsl,p1022-guts", },
+	{}
+};
+
+static int __init mpc85xx_cpufreq_init(void)
+{
+	struct device_node *np;
+
+	pr_info("Freescale MPC85xx CPU frequency switching driver\n");
+	np = of_find_matching_node(NULL, mpc85xx_jog_ids);
+	if (np == NULL)
+		return -ENODEV;
+
+	guts = of_iomap(np, 0);
+	of_node_put(np);
+	if (guts == NULL)
+		return -ENOMEM;
+
+	return cpufreq_register_driver(&mpc85xx_cpufreq_driver);
+}
+
+static void __exit mpc85xx_cpufreq_exit(void)
+{
+	iounmap(guts);
+
+	cpufreq_unregister_driver(&mpc85xx_cpufreq_driver);
+}
+
+module_init(mpc85xx_cpufreq_init);
+module_exit(mpc85xx_cpufreq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dave Liu <daveliu@freescale.com>");
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index b9ba861..64bddda 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -199,6 +199,14 @@ config CPU_FREQ_PMAC64
 	  This adds support for frequency switching on Apple iMac G5,
 	  and some of the more recent desktop G5 machines as well.
 
+config MPC85xx_CPUFREQ
+	bool "Support for Freescale MPC85xx CPU freq"
+	depends on PPC_85xx && PPC32
+	select CPU_FREQ_TABLE
+	help
+	  This adds support for frequency switching on Freescale MPC85xx,
+	  currently including P1022 and MPC8536.
+
 config PPC_PASEMI_CPUFREQ
 	bool "Support for PA Semi PWRficient"
 	depends on PPC_PASEMI
-- 
1.6.4.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox