* [PATCH 1/2] pinctrl: sirf: add pin group for USP0 with only RX or TX frame sync for atlas6
From: Linus Walleij @ 2014-02-04 20:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391061264-2162-1-git-send-email-21cnbao@gmail.com>
On Thu, Jan 30, 2014 at 6:54 AM, Barry Song <21cnbao@gmail.com> wrote:
> From: Rongjun Ying <rongjun.ying@csr.com>
>
> USP0 has multiple functions, and has RX and TX frame sync signals, for some scenarios
> like audio PCM, we don't need both of them. so here we add two possibilities for USP0
> only holding one of TX and RX frame sync.
>
> commit 8385af02bad only added this group for prima2, and missed atlas6. her this patch
> fixes it.
>
> Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
> Signed-off-by: Barry Song <Baohua.Song@csr.com>
Patch applied. Altered the commit message a bit.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH 2/2] ARM: dts: sirf: add pin group for USP0 with only RX or TX frame sync for atlas6
From: Linus Walleij @ 2014-02-04 20:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391061293-2195-1-git-send-email-21cnbao@gmail.com>
On Thu, Jan 30, 2014 at 6:54 AM, Barry Song <21cnbao@gmail.com> wrote:
> From: Rongjun Ying <rongjun.ying@csr.com>
>
> add pin groups for USP0 only holding one of TX and RX frame sync. this patch
> matches with the change in drivers/pinctrl/sirf.
>
> commit 73f68c01f46 did this for prima2, but missed prima2. this patch fixes
> the problem.
>
> Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
> Signed-off-by: Barry Song <Baohua.Song@csr.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Please take this patch through the ARM SoC tree.
Yours,
Linus Walleij
^ permalink raw reply
* [GIT PULL] tree-wide: clean up no longer required #include <linux/init.h>
From: Paul Gortmaker @ 2014-02-04 20:51 UTC (permalink / raw)
To: linux-arm-kernel
We've had this in linux-next for 2+ weeks (thanks Stephen!) as a
linux-stable like queue of patches, and as can be seen here:
https://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git
most of the changes in the last week have been trivial adding acks
or dropping patches that maintainers decided to take themselves.
With -rc1 now containing what was in linux-next, the queue applies
to that baseline w/o issue, and I've redone comprehensive multi
arch build testing on the -rc1 baseline as a final sanity check.
Original RFC discussion and patch posting is here, if needed:
https://lkml.org/lkml/2014/1/21/434
Suggested merge text follows:
----------------------------8<-----------------------------
Summary - We removed cpuinit and devinit, which left ~2000 instances
of include <linux/init.h> that were no longer needed. To fully enable
this removal/cleanup, we relocate module_init() from init.h into
module.h. Multi arch/multi config build testing on linux-next has
been used to find and fix any implicit header dependencies prior to
deploying the actual init.h --> module.h move, to preserve bisection.
Additional details:
module_init/module_exit and friends moved to module.h
-----------------------------------------------------
Aside from enabling this init.h cleanup to extend into modular files,
it actually does make sense. For all modules will use some form of
our initfunc processing/categorization, but not all initfunc users
will be necessarily using modular functionality. So we move these
module related macros to module.h and ensure module.h sources init.h
module_init in non modular code:
--------------------------------
This series uncovered that we are enabling people to use module_init
in non-modular code. While that works fine, there are at least three
reasons why it probably should not be encouraged:
1) it makes a casual reader of the code assume the code is modular
even though it is obj-y (builtin) or controlled by a bool Kconfig.
2) it makes it too easy to add dead code in a function that is handed
to module_exit() -- [more on that below]
3) it breaks our ability to use priority sorted initcalls properly
[more on that below.]
4) on some files, the use of module.h vs. init.h can cost a ~10%
increase in the number of lines output from CPP.
After this change, a new coder who tries to make use of module_init in
non modular code would find themselves also needing to include the
module.h header. At which point the odds are greater that they would
ask themselves "Am I doing this right? I shouldn't need this."
Note that existing non-modular code that already includes module.h and
uses module_init doesn't get fixed here, since they already build w/o
errors triggered by this change; we'll have to hunt them down later.
module_init and initcall ordering:
----------------------------------
We have a group of about ten priority sorted initcalls, that are
called in init/main.c after most of the hard coded/direct calls
have been processed. These serve the purpose of avoiding everyone
poking at init/main.c to hook in their init sequence. The bins are:
pure_initcall 0
core_initcall 1
postcore_initcall 2
arch_initcall 3
subsys_initcall 4
fs_initcall 5
device_initcall 6
late_initcall 7
These are meant to eventually replace users of the non specific
priority "__initcall" which currently maps onto device_initcall.
This is of interest, because in non-modular code, cpp does this:
module_init --> __initcall --> device_initcall
So all module_init() land in the device_initcall bucket, rather late
in the sequence. That makes sense, since if it was a module, the init
could be real late (days, weeks after boot). But now imagine you add
support for some non-modular bus/arch/infrastructure (say for e.g. PCI)
and you use module_init for it. That means anybody else who wants
to use your subsystem can't do so if they use an initcall of 0 --> 5
priority. For a real world example of this, see patch #1 in this series:
https://lkml.org/lkml/2014/1/14/809
We don't want to force code that is clearly arch or subsys or fs
specific to have to use the device_initcall just because something
else has been mistakenly put (or left) in that bucket. So a couple of
changes do actually change the initcall level where it is inevitably
appropriate to do so. Those are called out explicitly in their
respective commit logs.
module_exit and dead code
-------------------------
Built in code will never have an opportunity to call functions that
are registered with module_exit(), so any cases of that uncovered in
this series delete that dead code. Note that any built-in code that
was already including module.h and using module_exit won't have shown
up as breakage on the build coverage of this series, so we'll have to
find those independently later. It looks like there may be quite a
few that are invisibly created via module_platform_driver -- a macro
that creates module_init and module_exit automatically. We may want
to consider relocating module_platform_driver into module.h later...
cpuinit
-------
To finalize the removal of cpuinit, which was done several releases
ago, we remove the remaining stub functions from init.h in this
series. We've seen one or two "users" try to creep back in, so this
will close the door on that chapter and prevent creep.
----------------------------8<-----------------------------
Thanks,
Paul.
---
Cc: linux-alpha at vger.kernel.org
Cc: linux-arch at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-ia64 at vger.kernel.org
Cc: linux-m68k at lists.linux-m68k.org
Cc: linux-mips at linux-mips.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-s390 at vger.kernel.org
Cc: sparclinux at vger.kernel.org
Cc: x86 at kernel.org
Cc: netdev at vger.kernel.org
Cc: kvm at vger.kernel.org
Cc: sfr at canb.auug.org.au
Cc: rusty at rustcorp.com.au
Cc: gregkh at linuxfoundation.org
Cc: akpm at linux-foundation.org
Cc: torvalds@linux-foundation.org
The following changes since commit 38dbfb59d1175ef458d006556061adeaa8751b72:
Linus 3.14-rc1 (2014-02-02 16:42:13 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux.git tags/init-cleanup
for you to fetch changes up to a830e2e2777c893e5bfdaa370d6375023e8cd2a5:
include: remove needless instances of <linux/init.h> (2014-02-03 16:39:14 -0500)
----------------------------------------------------------------
Cleanup of <linux/init.h> for 3.14-rc1
----------------------------------------------------------------
Paul Gortmaker (77):
init: delete the __cpuinit related stubs
kernel: audit/fix non-modular users of module_init in core code
mm: replace module_init usages with subsys_initcall in nommu.c
fs/notify: don't use module_init for non-modular inotify_user code
netfilter: don't use module_init/exit in core IPV4 code
x86: don't use module_init in non-modular intel_mid_vrtc.c
x86: don't use module_init for non-modular core bootflag code
x86: replace __init_or_module with __init in non-modular vsmp_64.c
x86: don't use module_init in non-modular devicetree.c code
drivers/tty/hvc: don't use module_init in non-modular hyp. console code
staging: don't use module_init in non-modular ion_dummy_driver.c
powerpc: use device_initcall for registering rtc devices
powerpc: use subsys_initcall for Freescale Local Bus
powerpc: don't use module_init for non-modular core hugetlb code
powerpc: don't use module_init in non-modular 83xx suspend code
arm: include module.h in drivers/bus/omap_l3_smx.c
arm: fix implicit module.h use in mach-at91 gpio.h
arm: fix implicit #include <linux/init.h> in entry asm.
arm: mach-s3c64xx mach-crag6410-module.c is not modular
arm: use subsys_initcall in non-modular pl320 IPC code
arm: don't use module_init in non-modular mach-vexpress/spc.c code
alpha: don't use module_init for non-modular core code
m68k: don't use module_init in non-modular mvme16x/rtc.c code
ia64: don't use module_init for non-modular core kernel/mca.c code
ia64: don't use module_init in non-modular sim/simscsi.c code
mips: make loongsoon serial driver explicitly modular
mips: don't use module_init in non-modular sead3-mtd.c code
cris: don't use module_init for non-modular core intmem.c code
parisc: don't use module_init for non-modular core pdc_cons code
parisc64: don't use module_init for non-modular core perf code
mn10300: don't use module_init in non-modular flash.c code
sh: don't use module_init in non-modular psw.c code
sh: mach-highlander/psw.c is tristate and should use module.h
xtensa: don't use module_init for non-modular core network.c code
drivers/clk: don't use module_init in clk-nomadik.c which is non-modular
cpuidle: don't use modular platform register in non-modular ARM drivers
drivers/platform: don't use modular register in non-modular pdev_bus.c
module: relocate module_init from init.h to module.h
logo: emit "#include <linux/init.h> in autogenerated C file
arm: delete non-required instances of include <linux/init.h>
mips: restore init.h usage to arch/mips/ar7/time.c
s390: delete non-required instances of include <linux/init.h>
alpha: delete non-required instances of <linux/init.h>
powerpc: delete another unrequired instance of <linux/init.h>
arm64: delete non-required instances of <linux/init.h>
watchdog: delete non-required instances of include <linux/init.h>
video: delete non-required instances of include <linux/init.h>
rtc: delete non-required instances of include <linux/init.h>
scsi: delete non-required instances of include <linux/init.h>
spi: delete non-required instances of include <linux/init.h>
acpi: delete non-required instances of include <linux/init.h>
drivers/power: delete non-required instances of include <linux/init.h>
drivers/media: delete non-required instances of include <linux/init.h>
drivers/ata: delete non-required instances of include <linux/init.h>
drivers/hwmon: delete non-required instances of include <linux/init.h>
drivers/pinctrl: delete non-required instances of include <linux/init.h>
drivers/isdn: delete non-required instances of include <linux/init.h>
drivers/leds: delete non-required instances of include <linux/init.h>
drivers/pcmcia: delete non-required instances of include <linux/init.h>
drivers/char: delete non-required instances of include <linux/init.h>
drivers/infiniband: delete non-required instances of include <linux/init.h>
drivers/mfd: delete non-required instances of include <linux/init.h>
drivers/gpio: delete non-required instances of include <linux/init.h>
drivers/bluetooth: delete non-required instances of include <linux/init.h>
drivers/mmc: delete non-required instances of include <linux/init.h>
drivers/crypto: delete non-required instances of include <linux/init.h>
drivers/platform: delete non-required instances of include <linux/init.h>
drivers/misc: delete non-required instances of include <linux/init.h>
drivers/edac: delete non-required instances of include <linux/init.h>
drivers/macintosh: delete non-required instances of include <linux/init.h>
drivers/base: delete non-required instances of include <linux/init.h>
drivers/cpufreq: delete non-required instances of <linux/init.h>
drivers/pci: delete non-required instances of <linux/init.h>
drivers/dma: delete non-required instances of <linux/init.h>
drivers/gpu: delete non-required instances of <linux/init.h>
drivers: delete remaining non-required instances of <linux/init.h>
include: remove needless instances of <linux/init.h>
arch/alpha/kernel/err_ev6.c | 1 -
arch/alpha/kernel/irq.c | 1 -
arch/alpha/kernel/srmcons.c | 3 +-
arch/alpha/kernel/traps.c | 1 -
arch/alpha/oprofile/op_model_ev4.c | 1 -
arch/alpha/oprofile/op_model_ev5.c | 1 -
arch/alpha/oprofile/op_model_ev6.c | 1 -
arch/alpha/oprofile/op_model_ev67.c | 1 -
arch/arm/common/dmabounce.c | 1 -
arch/arm/firmware/trusted_foundations.c | 1 -
arch/arm/include/asm/arch_timer.h | 1 -
arch/arm/kernel/entry-armv.S | 2 +
arch/arm/kernel/entry-header.S | 1 -
arch/arm/kernel/hyp-stub.S | 1 -
arch/arm/kernel/suspend.c | 1 -
arch/arm/kernel/unwind.c | 1 -
arch/arm/mach-at91/include/mach/gpio.h | 1 +
arch/arm/mach-cns3xxx/pm.c | 1 -
arch/arm/mach-exynos/headsmp.S | 1 -
arch/arm/mach-footbridge/personal.c | 1 -
arch/arm/mach-imx/headsmp.S | 1 -
arch/arm/mach-imx/iomux-v3.c | 1 -
arch/arm/mach-iop33x/uart.c | 1 -
arch/arm/mach-msm/headsmp.S | 1 -
arch/arm/mach-msm/proc_comm.h | 1 -
arch/arm/mach-mvebu/headsmp.S | 1 -
arch/arm/mach-netx/fb.c | 1 -
arch/arm/mach-netx/pfifo.c | 1 -
arch/arm/mach-netx/xc.c | 1 -
arch/arm/mach-nspire/clcd.c | 1 -
arch/arm/mach-omap1/fpga.c | 1 -
arch/arm/mach-omap1/include/mach/serial.h | 1 -
arch/arm/mach-omap2/omap-headsmp.S | 1 -
arch/arm/mach-omap2/omap3-restart.c | 1 -
arch/arm/mach-omap2/vc3xxx_data.c | 1 -
arch/arm/mach-omap2/vc44xx_data.c | 1 -
arch/arm/mach-omap2/vp3xxx_data.c | 1 -
arch/arm/mach-omap2/vp44xx_data.c | 1 -
arch/arm/mach-prima2/headsmp.S | 1 -
arch/arm/mach-pxa/clock-pxa2xx.c | 1 -
arch/arm/mach-pxa/clock-pxa3xx.c | 1 -
arch/arm/mach-pxa/corgi_pm.c | 1 -
arch/arm/mach-pxa/mfp-pxa3xx.c | 1 -
arch/arm/mach-pxa/spitz_pm.c | 1 -
arch/arm/mach-s3c24xx/clock-s3c244x.c | 1 -
arch/arm/mach-s3c24xx/iotiming-s3c2410.c | 1 -
arch/arm/mach-s3c24xx/iotiming-s3c2412.c | 1 -
arch/arm/mach-s3c24xx/irq-pm.c | 1 -
arch/arm/mach-s3c24xx/pm.c | 1 -
arch/arm/mach-s3c64xx/mach-crag6410-module.c | 2 +-
arch/arm/mach-s5p64x0/clock.c | 1 -
arch/arm/mach-sa1100/ssp.c | 1 -
arch/arm/mach-shmobile/headsmp-scu.S | 1 -
arch/arm/mach-shmobile/headsmp.S | 1 -
arch/arm/mach-shmobile/platsmp.c | 1 -
arch/arm/mach-shmobile/sleep-sh7372.S | 1 -
arch/arm/mach-socfpga/headsmp.S | 1 -
arch/arm/mach-sti/headsmp.S | 1 -
arch/arm/mach-sunxi/headsmp.S | 1 -
arch/arm/mach-tegra/flowctrl.c | 1 -
arch/arm/mach-tegra/headsmp.S | 1 -
arch/arm/mach-tegra/reset-handler.S | 1 -
arch/arm/mach-u300/dummyspichip.c | 1 -
arch/arm/mach-ux500/board-mop500-audio.c | 1 -
arch/arm/mach-ux500/headsmp.S | 1 -
arch/arm/mach-versatile/versatile_ab.c | 1 -
arch/arm/mach-vexpress/spc.c | 2 +-
arch/arm/mach-zynq/headsmp.S | 1 -
arch/arm/mm/hugetlbpage.c | 1 -
arch/arm/plat-iop/i2c.c | 1 -
arch/arm/plat-samsung/pm-check.c | 1 -
arch/arm/plat-samsung/pm-gpio.c | 1 -
arch/arm/plat-samsung/s5p-irq-pm.c | 1 -
arch/arm/plat-versatile/headsmp.S | 1 -
arch/arm/plat-versatile/platsmp.c | 1 -
arch/arm/vfp/entry.S | 2 +
arch/arm64/include/asm/arch_timer.h | 1 -
arch/arm64/kernel/cputable.c | 2 -
arch/arm64/kernel/entry.S | 1 -
arch/arm64/kernel/hyp-stub.S | 1 -
arch/arm64/kernel/process.c | 1 -
arch/arm64/kernel/ptrace.c | 1 -
arch/arm64/kernel/smp_spin_table.c | 1 -
arch/arm64/kernel/vdso/vdso.S | 1 -
arch/arm64/lib/delay.c | 1 -
arch/arm64/mm/cache.S | 1 -
arch/arm64/mm/proc.S | 1 -
arch/cris/arch-v32/mm/intmem.c | 3 +-
arch/ia64/hp/sim/simscsi.c | 11 +---
arch/ia64/sn/kernel/mca.c | 3 +-
arch/m68k/mvme16x/rtc.c | 2 +-
arch/mips/ar7/time.c | 1 +
arch/mips/loongson/common/serial.c | 9 ++-
arch/mips/mti-sead3/sead3-mtd.c | 3 +-
arch/mn10300/unit-asb2303/flash.c | 3 +-
arch/parisc/kernel/pdc_cons.c | 3 +-
arch/parisc/kernel/perf.c | 3 +-
arch/powerpc/kernel/time.c | 2 +-
arch/powerpc/mm/hugetlbpage.c | 2 +-
arch/powerpc/platforms/83xx/suspend.c | 3 +-
arch/powerpc/platforms/ps3/time.c | 3 +-
arch/powerpc/sysdev/fsl_lbc.c | 2 +-
arch/powerpc/sysdev/indirect_pci.c | 1 -
arch/sh/boards/mach-highlander/psw.c | 2 +-
arch/sh/boards/mach-landisk/psw.c | 2 +-
arch/x86/kernel/bootflag.c | 2 +-
arch/x86/kernel/devicetree.c | 2 +-
arch/x86/kernel/vsmp_64.c | 2 +-
arch/x86/platform/intel-mid/intel_mid_vrtc.c | 3 +-
arch/xtensa/platforms/iss/network.c | 4 +-
drivers/acpi/apei/apei-base.c | 1 -
drivers/acpi/button.c | 1 -
[ ... snip ~1000 lines of trivial driver diffstat ... ]
drivers/watchdog/wdt_pci.c | 1 -
drivers/xen/xen-stub.c | 1 -
fs/notify/inotify/inotify_user.c | 4 +-
include/drm/drmP.h | 1 -
include/linux/fb.h | 1 -
include/linux/ide.h | 1 -
include/linux/init.h | 77 ----------------------
include/linux/kdb.h | 1 -
include/linux/linux_logo.h | 3 -
include/linux/lsm_audit.h | 1 -
include/linux/module.h | 72 ++++++++++++++++++++
include/linux/moduleparam.h | 1 -
include/linux/netfilter.h | 1 -
include/linux/nls.h | 2 +-
include/linux/percpu_ida.h | 1 -
include/linux/profile.h | 1 -
include/linux/pstore_ram.h | 1 -
include/linux/usb/gadget.h | 1 -
include/xen/xenbus.h | 1 -
kernel/hung_task.c | 3 +-
kernel/kexec.c | 4 +-
kernel/profile.c | 2 +-
kernel/sched/stats.c | 2 +-
kernel/user.c | 3 +-
kernel/user_namespace.c | 2 +-
mm/nommu.c | 4 +-
net/ipv4/netfilter.c | 9 +--
scripts/pnmtologo.c | 1 +
scripts/tags.sh | 2 +-
1115 files changed, 148 insertions(+), 1273 deletions(-)
^ permalink raw reply
* [PATCH 2/4] pinctrl: st: add stid127 support
From: Linus Walleij @ 2014-02-04 20:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391093744-19905-3-git-send-email-patrice.chotard@st.com>
On Thu, Jan 30, 2014 at 3:55 PM, Patrice CHOTARD <patrice.chotard@st.com> wrote:
> From: Alexandre TORGUE <alexandre.torgue@st.com>
>
> Add STid127 PIOs (psouth, pwest, peast) in pinctrl.
>
> Signed-off-by: alexandre torgue <alexandre.torgue@st.com>
Patch applied with Srinivas ACK.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v5 4/6] spmi: pmic_arb: add support for interrupt handling
From: Josh Cartwright @ 2014-02-04 20:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.02.1402042107311.24986@ionos.tec.linutronix.de>
On Tue, Feb 04, 2014 at 09:10:45PM +0100, Thomas Gleixner wrote:
> On Mon, 3 Feb 2014, Josh Cartwright wrote:
> > +static void qpnpint_irq_ack(struct irq_data *d)
> > +{
> > + struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
> > + u8 irq = d->hwirq >> 8;
> > + u8 apid = d->hwirq;
> > + unsigned long flags;
> > + u8 data;
> > +
> > + spin_lock_irqsave(&pa->lock, flags);
>
> This wants to be a raw_spinlock - think about RT!
Indeed. I'll change this in the next revision.
> Looks sane otherwise.
Great, thanks for taking a look!
Josh
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* [GIT PULL] irqchip: dove: drivers for v3.14
From: Jason Cooper @ 2014-02-04 21:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.02.1402041959110.24986@ionos.tec.linutronix.de>
On Tue, Feb 04, 2014 at 07:59:58PM +0100, Thomas Gleixner wrote:
> On Tue, 28 Jan 2014, Jason Cooper wrote:
> > I see you pulled in mvebu/irqchip-fixes. Thanks for that. It's getting
> > near to the end of the merge window and there's been no activity on this
> > pull request.
> >
> > Please let us know if there's anything we can do to assist.
>
> Nah. I simply forgot about it. About to send a pull request to Linus.
hmmm. I see the pull request contains the patches from
mvebu/irqchip-fixes (armada), but not the patches from mvebu/irqchip
(dove):
40b367d95fb3 irqchip: irq-dove: Add PMU interrupt controller.
which is what this thread was originally a pull request for.
Are you planning to send a second pull request to Linus?
thx,
Jason.
^ permalink raw reply
* [PATCH 2/6] regulator: add bcm59056 pmu DT binding
From: Matt Porter @ 2014-02-04 21:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204172309.GG22609@sirena.org.uk>
On Tue, Feb 04, 2014 at 05:23:09PM +0000, Mark Brown wrote:
> On Tue, Feb 04, 2014 at 07:19:08AM -0500, Matt Porter wrote:
> > Add a DT binding for the BCM59056 PMU. The binding inherits from
> > the generic regulator bindings.
>
> Is this really only a regulator - does the chip have no other functions?
It's your average multi-function device with other functions as you are
suspecting. Buried in the the MFD driver comments is me admitting that
I need to split this into two bindings. The base device, "bcm59056" and
then "bcm59056-reg". So point noted, I'll updated with the appropriate
binding for each.
> > +- regulators: This is the list of child nodes that specify the regulator
> > + initialization data for defined regulators. Generic regulator bindings
> > + are described in regulator/regulator.txt.
>
> The regulators property should always be optional, the driver should be
> able to start up and read back the hardware state without any further
> configuration.
Ahh, ok. I will make it so.
Thanks,
Matt
^ permalink raw reply
* [Patch v5 1/2] dmaengine: add Qualcomm BAM dma driver
From: Joe Perches @ 2014-02-04 21:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391546556-27702-2-git-send-email-agross@codeaurora.org>
On Tue, 2014-02-04 at 14:42 -0600, Andy Gross wrote:
> Add the DMA engine driver for the QCOM Bus Access Manager (BAM) DMA controller
> found in the MSM 8x74 platforms.
trivia: fixable later.
> diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
[]
> + /* allocate enough room to accomodate the number of entries */
> + async_desc = kzalloc(sizeof(*async_desc) +
> + (sg_len * sizeof(struct bam_desc_hw)), GFP_NOWAIT);
> +
> + if (!async_desc) {
> + dev_err(bdev->dev, "failed to allocate async descriptor\n");
Unnecessary OOM message as generic alloc has an
OOM message with a dump_stack();
> +static int bam_dma_probe(struct platform_device *pdev)
> +{
[]
> + ret = clk_prepare_enable(bdev->bamclk);
> + if (ret) {
> + dev_err(bdev->dev, "failed to prepare/enable clock");
Missing terminating \n newline
^ permalink raw reply
* [PATCH 4/6] regulator: add bcm59056 regulator driver
From: Matt Porter @ 2014-02-04 21:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204172836.GH22609@sirena.org.uk>
On Tue, Feb 04, 2014 at 05:28:36PM +0000, Mark Brown wrote:
> On Tue, Feb 04, 2014 at 07:19:10AM -0500, Matt Porter wrote:
>
> > +static unsigned int bcm59056_get_mode(struct regulator_dev *dev)
> > +{
> > + return REGULATOR_MODE_NORMAL;
> > +}
> > +
> > +static int bcm59056_set_mode(struct regulator_dev *dev, unsigned int mode)
> > +{
> > + if (mode == REGULATOR_MODE_NORMAL)
> > + return 0;
> > + else
> > + return -EINVAL;
> > +}
>
> These do nothing, don't implement them.
Will remove. Maybe some day.
> > + if (bcm59056->dev->of_node)
> > + pmu_data = bcm59056_parse_dt_reg_data(pdev,
> > + &bcm59056_reg_matches);
>
> It'd seem a bit neater to put the OF check into the parse function but
> meh.
On second look, I'd agree. Easy enough to clean up.
> > + if (!pmu_data) {
> > + dev_err(&pdev->dev, "Platform data not found\n");
> > + return -EINVAL;
> > + }
>
> Like I said when reviewing the binding this should not cause the driver
> to fail to load.
Will fix.
> > + /*
> > + * Regulator API handles empty constraints but not NULL
> > + * constraints
> > + */
> > + if (!reg_data)
> > + continue;
>
> It should do... if not then make it so since that'd mean most drivers
> are buggy.
Ahh, I see there is a check for NULL in the core. Will drop.
-Matt
^ permalink raw reply
* [GIT PULL] irqchip: dove: drivers for v3.14
From: Thomas Gleixner @ 2014-02-04 21:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204211219.GK8533@titan.lakedaemon.net>
On Tue, 4 Feb 2014, Jason Cooper wrote:
> On Tue, Feb 04, 2014 at 07:59:58PM +0100, Thomas Gleixner wrote:
> > On Tue, 28 Jan 2014, Jason Cooper wrote:
> > > I see you pulled in mvebu/irqchip-fixes. Thanks for that. It's getting
> > > near to the end of the merge window and there's been no activity on this
> > > pull request.
> > >
> > > Please let us know if there's anything we can do to assist.
> >
> > Nah. I simply forgot about it. About to send a pull request to Linus.
>
> hmmm. I see the pull request contains the patches from
> mvebu/irqchip-fixes (armada), but not the patches from mvebu/irqchip
> (dove):
>
> 40b367d95fb3 irqchip: irq-dove: Add PMU interrupt controller.
>
> which is what this thread was originally a pull request for.
>
>
> Are you planning to send a second pull request to Linus?
Duh. I'll pick that up tomorrow
^ permalink raw reply
* Extending OPP bindings
From: Nishanth Menon @ 2014-02-04 21:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204201122.GB22609@sirena.org.uk>
On 02/04/2014 02:11 PM, Mark Brown wrote:
> On Tue, Feb 04, 2014 at 01:28:20PM -0600, Nishanth Menon wrote:
>> On 02/04/2014 12:22 PM, Mark Brown wrote:
>
>>> You're assuming that the frequency is a unique key here. That may not
>>> be the case, for example two OPPs might have the same CPU clock
>>> (assuming that's the frequency you're referring to) but different bus
>>> clocking and of course the CPUs or CPU clusters might be individually
>>> scalable (this is common in big.LITTLE designs I think).
>
>> Which is why OPPs are maintained per device, bus OPPs belong to bus
>> device (in TI terminology, we'd be talking of cross domain dependency
>> here for maintaining asynchronous bridge timing closure constraints -
>> but ofcourse, other SoCs may or maynot have such constraints). For
>> scaling bus frequency, we already have infrastructure in place - clock
>> notifiers - discussion of using that is much deeper topic of it's own.
>
>> for each processor that is uniquely transitioning, we'd have it's own
>> sets of OPPs - the correct representation of the device node is the
>> key there.
>
> I've seen some SoCs characterised over the whole device rather than with
> individual parts of the SoC done separately.
>
Fair enough - however, the data characterized will imply individual
processor/bus specific tuples/parameters - the specific parameters
might be very unique for SoC, but we have ability to abstract it per
SoC already.
--
Regards,
Nishanth Menon
^ permalink raw reply
* [PATCH] dma: mv_xor: Silence a bunch of LPAE-related warnings
From: Olof Johansson @ 2014-02-04 21:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAPcyv4jwwRT_+c-yDycgY0d79nByvAVWH6waFWeodE9yi=7CDg@mail.gmail.com>
On Tue, Feb 4, 2014 at 10:57 AM, Dan Williams <dan.j.williams@intel.com> wrote:
> On Tue, Feb 4, 2014 at 10:30 AM, Olof Johansson <olof@lixom.net> wrote:
>> On Tue, Feb 4, 2014 at 9:00 AM, Jason Cooper <jason@lakedaemon.net> wrote:
>>> On Tue, Feb 04, 2014 at 10:53:29AM +0530, Vinod Koul wrote:
>>>> On Mon, Feb 03, 2014 at 05:13:23PM -0800, Olof Johansson wrote:
>>>> > Enabling some of the mvebu platforms in the multiplatform config for ARM
>>>> > enabled these drivers, which also triggered a bunch of warnings when LPAE
>>>> > is enabled (thus making phys_addr_t 64-bit).
>>>> >
>>>> > Most changes are switching printk formats, but also a bit of changes to what
>>>> > used to be array-based pointer arithmetic that could just be done with the
>>>> > address types instead.
>>>> >
>>>> > The warnings were:
>>>> >
>>>> > drivers/dma/mv_xor.c: In function 'mv_xor_tx_submit':
>>>> > drivers/dma/mv_xor.c:500:3: warning: format '%x' expects argument of type
>>>> > 'unsigned int', but argument 4 has type 'dma_addr_t' [-Wformat]
>>>> > drivers/dma/mv_xor.c: In function 'mv_xor_alloc_chan_resources':
>>>> > drivers/dma/mv_xor.c:553:13: warning: cast to pointer from integer of
>>>> > different size [-Wint-to-pointer-cast]
>>>> > drivers/dma/mv_xor.c:555:4: warning: cast from pointer to integer of
>>>> > different size [-Wpointer-to-int-cast]
>>>> > drivers/dma/mv_xor.c: In function 'mv_xor_prep_dma_memcpy':
>>>> > drivers/dma/mv_xor.c:584:2: warning: format '%x' expects argument of type
>>>> > 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat]
>>>> > drivers/dma/mv_xor.c:584:2: warning: format '%x' expects argument of type
>>>> > 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat]
>>>> > drivers/dma/mv_xor.c: In function 'mv_xor_prep_dma_xor':
>>>> > drivers/dma/mv_xor.c:628:2: warning: format '%u' expects argument of type
>>>> > 'unsigned int', but argument 7 has type 'dma_addr_t' [-Wformat]
>>>> >
>>>> > Signed-off-by: Olof Johansson <olof@lixom.net>
>>>> Acked-by: Vinod Koul <vinod.koul@intel.com>
>>>
>>> Olof, would you like me to queue it up? Or do you want to take it
>>> directly?
>>>
>>> Acked-by: Jason Cooper <jason@lakedaemon.net>
>>
>> I'm confused. I sent the patch to the drivers/dma maintainers and they
>> just acked it without asking me to pick it up myself.
>>
>> Vinod, did you ack it for me to pick it up, or for some other reason?
>> If you don't want to take it through your tree I'll be happy to take
>> it through arm-soc, just looking to clarify.
>>
>> (Jason, I can apply it directly)
>
> Vinod will correct me if I am wrong, but I take his acks to mean "yup,
> take it through your tree".
Ok, thanks, we'll do that then.
-Olof
^ permalink raw reply
* Weird sched_clock behaviour during boot with -rc1
From: Stephen Boyd @ 2014-02-04 22:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F1518B.9010109@linaro.org>
On 02/04, John Stultz wrote:
> On 02/04/2014 10:36 AM, Will Deacon wrote:
> > Hi guys,
> >
> > Booting -rc1 on my TC2 gives the following strange entries in the dmesg:
> >
> >
> > Uncompressing Linux... done, booting the kernel.
> > [ 0.000000] Booting Linux on physical CPU 0x0
> >
> > [...]
> >
> > [ 0.000000] HighMem zone: 329728 pages, LIFO batch:31
> > [ 7.789662] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956969942ns
> > [ 0.000129] PERCPU: Embedded 9 pages/cpu @ee7bd000 s12800 r8192 d15872 u36864
> >
> > [...]
> >
> > [ 0.868297] NR_IRQS:16 nr_irqs:16 16
> > [ 0.886350] Architected cp15 timer(s) running at 24.00MHz (phys).
> > [ 2915.164998] sched_clock: 56 bits at 24MHz, resolution 41ns, wraps every 2863311519744ns
> > [ 0.000002] Switching to timer-based delay loop
> > [ 0.014249] Console: colour dummy device 80x30
> >
> >
> > so it looks like something whacky goes on during sched_clock registration.
> > Sure enough, we're doing a pr_info in-between updating cs.* and calling
> > update_sched_clock(), so moving the print sorts things out (diff below).
>
> Yea... we have to be particularly careful with sched_clock to avoid
> locks since we don't want to deadlock, but in this case
> sched_clock_register is a little too relaxed here.
>
> Stephen: Would it make sense to set cd.suspended = true at the top of
> the registration? That should block any sched_clock calls from getting
> half-updated data, but still allow the sched_clock_update function to work.
>
That would work, but why can't we just hold the write seqlock
during the registration? We would need to make a lockeless
version of update_sched_clock() but that doesn't look too hard.
It might actually turn out nicer because we call
update_sched_clock() here just to set the epoch_cyc but we have
to reset the epoch_ns back to 0 to start the count off right.
How about this? The only concern is calling read_sched_clock()
inside the seqlock, but I don't think that's a concern and if it
is we can call it outside the lock at the beginning of this
function.
----8<----
diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c
index 0abb36464281..ae8f10a02c32 100644
--- a/kernel/time/sched_clock.c
+++ b/kernel/time/sched_clock.c
@@ -124,6 +124,7 @@ void __init sched_clock_register(u64 (*read)(void), int bits,
return;
WARN_ON(!irqs_disabled());
+ raw_write_seqcount_begin(&cd.seq);
read_sched_clock = read;
sched_clock_mask = CLOCKSOURCE_MASK(bits);
cd.rate = rate;
@@ -147,15 +148,16 @@ void __init sched_clock_register(u64 (*read)(void), int bits,
/* calculate the ns resolution of this counter */
res = cyc_to_ns(1ULL, cd.mult, cd.shift);
- pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lluns\n",
- bits, r, r_unit, res, wrap);
-
- update_sched_clock();
/*
* Ensure that sched_clock() starts off at 0ns
*/
cd.epoch_ns = 0;
+ cd.epoch_cyc = read_sched_clock();
+ raw_write_seqcount_end(&cd.seq);
+
+ pr_info("sched_clock: %u bits@%lu%cHz, resolution %lluns, wraps every %lluns\n",
+ bits, r, r_unit, res, wrap);
/* Enable IRQ time accounting if we have a fast enough sched_clock */
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH] ARM: spinlock: ensure we have a compiler barrier before sev
From: Christoffer Dall @ 2014-02-04 22:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391516926-14493-1-git-send-email-will.deacon@arm.com>
On Tue, Feb 04, 2014 at 12:28:46PM +0000, Will Deacon wrote:
> When unlocking a spinlock, we require the following, strictly ordered
> sequence of events:
>
> <barrier> /* dmb */
> <unlock>
> <barrier> /* dsb */
> <sev>
>
> Whilst the code does indeed reflect this in terms of the architecture,
> the final <barrier> + <sev> have been contracted into a single inline
> asm without a "memory" clobber, therefore the compiler is at liberty to
> reorder the unlock to the end of the above sequence. In such a case,
> a waiting CPU may be woken up before the lock has been unlocked, leading
> to extremely poor performance.
>
> This patch reworks the dsb_sev() function to make use of the dsb()
> macro and ensure ordering against the unlock.
>
> Cc: <stable@vger.kernel.org>
> Reported-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
FWIW: Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
^ permalink raw reply
* [PATCH v4 1/3] clocksource: timer-keystone: introduce clocksource driver for Keystone
From: Santosh Shilimkar @ 2014-02-04 22:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.02.1402042113270.24986@ionos.tec.linutronix.de>
On Tuesday 04 February 2014 03:17 PM, Thomas Gleixner wrote:
> On Tue, 4 Feb 2014, Ivan Khoronzhuk wrote:
>
> Please do not top post.
>
>> It was so in v1. But it was decided to use explicit memory barriers,
>> because we're always sure the memory barriers are there and that
>> they're properly documented. Also in this case I don't need to add
>> keystone readl/writel relaxed function variants and to use mixed calls of
>> writel/writel_relaxed functions.
>>
>> See:
>> http://www.spinics.net/lists/arm-kernel/msg294941.html
>
> Fair enough, but we want a proper explanation for explicit barriers in
> the code and not in some random discussion of patch version X on some
> random mailing list.
>
> Aside of that it should be iowmb(), but I might miss something ...
>
Agree. __iowmb() seems to be more appropriate.
Regards,
Santosh
^ permalink raw reply
* [PATCH v4 1/3] clocksource: timer-keystone: introduce clocksource driver for Keystone
From: Ivan Khoronzhuk @ 2014-02-04 22:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F1668B.9040507@ti.com>
Yes. I'll send with __iowmb() instead of wmb().
On 02/05/2014 12:15 AM, Santosh Shilimkar wrote:
> On Tuesday 04 February 2014 03:17 PM, Thomas Gleixner wrote:
>> On Tue, 4 Feb 2014, Ivan Khoronzhuk wrote:
>>
>> Please do not top post.
>>
>>> It was so in v1. But it was decided to use explicit memory barriers,
>>> because we're always sure the memory barriers are there and that
>>> they're properly documented. Also in this case I don't need to add
>>> keystone readl/writel relaxed function variants and to use mixed calls of
>>> writel/writel_relaxed functions.
>>>
>>> See:
>>> http://www.spinics.net/lists/arm-kernel/msg294941.html
>> Fair enough, but we want a proper explanation for explicit barriers in
>> the code and not in some random discussion of patch version X on some
>> random mailing list.
>>
>> Aside of that it should be iowmb(), but I might miss something ...
>>
> Agree. __iowmb() seems to be more appropriate.
>
> Regards,
> Santosh
>
--
Regards,
Ivan Khoronzhuk
^ permalink raw reply
* [PATCH v2 0/5] Split mach-msm into legacy and mach-qcom (multiplatform)
From: Kumar Gala @ 2014-02-04 22:36 UTC (permalink / raw)
To: linux-arm-kernel
This is the splits the Qualcomm MSM platform into legacy support that we will
not try and convert to multiplatform and multiplatform support.
- k
Changes from v1:
* Added patch to remove hotplug.c
* Added patch to rename msm_ to qcom_
* Changes the Kconfig to drop CPU_V7
* used wfi() in cpu_die function
* Added git tree to MAINTAINERS file
Kumar Gala (5):
ARM: msm: kill off hotplug.c
clocksource: qcom: Move clocksource code out of mach-msm
arm: qcom: Split Qualcomm support into legacy and multiplatform
clocksource: qcom: split building of legacy vs multiplatform support
ARM: qcom: Rename various msm prefixed functions to qcom
arch/arm/mach-msm/board-dt.c | 41 ----
arch/arm/mach-msm/hotplug.c | 51 -----
arch/arm/mach-msm/platsmp.c | 130 --------------
arch/arm/mach-msm/scm-boot.c | 39 ----
arch/arm/mach-msm/scm-boot.h | 22 --
arch/arm/mach-msm/scm.c | 299 ---------------------------------
arch/arm/mach-msm/scm.h | 25 --
arch/arm/mach-msm/timer.c | 333 -------------------------------------
b/MAINTAINERS | 8
b/arch/arm/Kconfig | 7
b/arch/arm/Kconfig.debug | 2
b/arch/arm/Makefile | 1
b/arch/arm/boot/dts/Makefile | 6
b/arch/arm/mach-msm/Kconfig | 54 ------
b/arch/arm/mach-msm/Makefile | 8
b/arch/arm/mach-msm/common.h | 1
b/arch/arm/mach-qcom/Kconfig | 33 +++
b/arch/arm/mach-qcom/Makefile | 5
b/arch/arm/mach-qcom/board.c | 40 ++++
b/arch/arm/mach-qcom/scm-boot.c | 39 ++++
b/arch/arm/mach-qcom/scm-boot.h | 22 ++
b/arch/arm/mach-qcom/scm.c | 299 +++++++++++++++++++++++++++++++++
b/arch/arm/mach-qcom/scm.h | 25 ++
b/arch/arm/mach-qcom/smp.c | 137 +++++++++++++++
b/drivers/clocksource/Kconfig | 4
b/drivers/clocksource/Makefile | 1
b/drivers/clocksource/qcom-timer.c | 330 ++++++++++++++++++++++++++++++++++++
27 files changed, 957 insertions(+), 1005 deletions(-)
^ permalink raw reply
* [PATCH 1/5] ARM: msm: kill off hotplug.c
From: Kumar Gala @ 2014-02-04 22:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391553421-26914-1-git-send-email-galak@codeaurora.org>
Right now hotplug.c only really implements msm_cpu_die as a wfi. Just
move that implementation into platsmp.c. At the same time we use the
existing wfi() instead of inline asm.
Signed-off-by: Kumar Gala <galak@codeaurora.org>
---
arch/arm/mach-msm/Makefile | 1 -
arch/arm/mach-msm/common.h | 1 -
arch/arm/mach-msm/hotplug.c | 51 ---------------------------------------------
arch/arm/mach-msm/platsmp.c | 7 +++++++
4 files changed, 7 insertions(+), 53 deletions(-)
delete mode 100644 arch/arm/mach-msm/hotplug.c
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 721f27f..8327f60 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
-obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
diff --git a/arch/arm/mach-msm/common.h b/arch/arm/mach-msm/common.h
index 33c7725..0a4899b 100644
--- a/arch/arm/mach-msm/common.h
+++ b/arch/arm/mach-msm/common.h
@@ -24,7 +24,6 @@ extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
unsigned int mtype, void *caller);
extern struct smp_operations msm_smp_ops;
-extern void msm_cpu_die(unsigned int cpu);
struct msm_mmc_platform_data;
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
deleted file mode 100644
index cea80fc..0000000
--- a/arch/arm/mach-msm/hotplug.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2002 ARM Ltd.
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
-
-#include <asm/smp_plat.h>
-
-#include "common.h"
-
-static inline void cpu_enter_lowpower(void)
-{
-}
-
-static inline void cpu_leave_lowpower(void)
-{
-}
-
-static inline void platform_do_lowpower(unsigned int cpu)
-{
- asm("wfi"
- :
- :
- : "memory", "cc");
-}
-
-/*
- * platform-specific code to shutdown a CPU
- *
- * Called with IRQs disabled
- */
-void __ref msm_cpu_die(unsigned int cpu)
-{
- /*
- * we're ready for shutdown now, so do it
- */
- cpu_enter_lowpower();
- platform_do_lowpower(cpu);
-
- /*
- * bring this CPU back into the world of cache
- * coherency, and then restore interrupts
- */
- cpu_leave_lowpower();
-}
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 3721b31..251a91e 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -29,6 +29,13 @@ extern void secondary_startup(void);
static DEFINE_SPINLOCK(boot_lock);
+#ifdef CONFIG_HOTPLUG_CPU
+static void __ref msm_cpu_die(unsigned int cpu)
+{
+ wfi();
+}
+#endif
+
static inline int get_core_count(void)
{
/* 1 + the PART[1:0] field of MIDR */
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH 2/5] clocksource: qcom: Move clocksource code out of mach-msm
From: Kumar Gala @ 2014-02-04 22:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391553421-26914-1-git-send-email-galak@codeaurora.org>
We intent to share the clocksource code for MSM platforms between legacy
and multiplatform supported qcom SoCs.
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Kumar Gala <galak@codeaurora.org>
---
arch/arm/mach-msm/Kconfig | 13 +-
arch/arm/mach-msm/Makefile | 1 -
arch/arm/mach-msm/timer.c | 333 ---------------------------------------
drivers/clocksource/Kconfig | 4 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/qcom-timer.c | 329 ++++++++++++++++++++++++++++++++++++++
6 files changed, 339 insertions(+), 342 deletions(-)
delete mode 100644 arch/arm/mach-msm/timer.c
create mode 100644 drivers/clocksource/qcom-timer.c
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 9625cf3..3c4eca7 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -21,7 +21,7 @@ config ARCH_MSM8X60
select CPU_V7
select HAVE_SMP
select MSM_SCM if SMP
- select MSM_TIMER
+ select CLKSRC_QCOM
config ARCH_MSM8960
bool "Enable support for MSM8960"
@@ -29,7 +29,7 @@ config ARCH_MSM8960
select CPU_V7
select HAVE_SMP
select MSM_SCM if SMP
- select MSM_TIMER
+ select CLKSRC_QCOM
config ARCH_MSM8974
bool "Enable support for MSM8974"
@@ -54,7 +54,7 @@ config ARCH_MSM7X00A
select MACH_TROUT if !MACH_HALIBUT
select MSM_PROC_COMM
select MSM_SMD
- select MSM_TIMER
+ select CLKSRC_QCOM
select MSM_SMD_PKG3
config ARCH_MSM7X30
@@ -66,7 +66,7 @@ config ARCH_MSM7X30
select MSM_GPIOMUX
select MSM_PROC_COMM
select MSM_SMD
- select MSM_TIMER
+ select CLKSRC_QCOM
select MSM_VIC
config ARCH_QSD8X50
@@ -78,7 +78,7 @@ config ARCH_QSD8X50
select MSM_GPIOMUX
select MSM_PROC_COMM
select MSM_SMD
- select MSM_TIMER
+ select CLKSRC_QCOM
select MSM_VIC
endchoice
@@ -153,7 +153,4 @@ config MSM_GPIOMUX
config MSM_SCM
bool
-config MSM_TIMER
- bool
-
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 8327f60..04b1bee 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,4 +1,3 @@
-obj-$(CONFIG_MSM_TIMER) += timer.o
obj-$(CONFIG_MSM_PROC_COMM) += clock.o
obj-$(CONFIG_MSM_VIC) += irq-vic.o
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
deleted file mode 100644
index fd16449..0000000
--- a/arch/arm/mach-msm/timer.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- *
- * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/cpu.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/sched_clock.h>
-
-#include <asm/mach/time.h>
-
-#include "common.h"
-
-#define TIMER_MATCH_VAL 0x0000
-#define TIMER_COUNT_VAL 0x0004
-#define TIMER_ENABLE 0x0008
-#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1)
-#define TIMER_ENABLE_EN BIT(0)
-#define TIMER_CLEAR 0x000C
-#define DGT_CLK_CTL 0x10
-#define DGT_CLK_CTL_DIV_4 0x3
-#define TIMER_STS_GPT0_CLR_PEND BIT(10)
-
-#define GPT_HZ 32768
-
-#define MSM_DGT_SHIFT 5
-
-static void __iomem *event_base;
-static void __iomem *sts_base;
-
-static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
-{
- struct clock_event_device *evt = dev_id;
- /* Stop the timer tick */
- if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
- u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
- ctrl &= ~TIMER_ENABLE_EN;
- writel_relaxed(ctrl, event_base + TIMER_ENABLE);
- }
- evt->event_handler(evt);
- return IRQ_HANDLED;
-}
-
-static int msm_timer_set_next_event(unsigned long cycles,
- struct clock_event_device *evt)
-{
- u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-
- ctrl &= ~TIMER_ENABLE_EN;
- writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-
- writel_relaxed(ctrl, event_base + TIMER_CLEAR);
- writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
-
- if (sts_base)
- while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
- cpu_relax();
-
- writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
- return 0;
-}
-
-static void msm_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- u32 ctrl;
-
- ctrl = readl_relaxed(event_base + TIMER_ENABLE);
- ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
-
- switch (mode) {
- case CLOCK_EVT_MODE_RESUME:
- case CLOCK_EVT_MODE_PERIODIC:
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- /* Timer is enabled in set_next_event */
- break;
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- break;
- }
- writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-}
-
-static struct clock_event_device __percpu *msm_evt;
-
-static void __iomem *source_base;
-
-static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
-{
- return readl_relaxed(source_base + TIMER_COUNT_VAL);
-}
-
-static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
-{
- /*
- * Shift timer count down by a constant due to unreliable lower bits
- * on some targets.
- */
- return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
-}
-
-static struct clocksource msm_clocksource = {
- .name = "dg_timer",
- .rating = 300,
- .read = msm_read_timer_count,
- .mask = CLOCKSOURCE_MASK(32),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static int msm_timer_irq;
-static int msm_timer_has_ppi;
-
-static int msm_local_timer_setup(struct clock_event_device *evt)
-{
- int cpu = smp_processor_id();
- int err;
-
- evt->irq = msm_timer_irq;
- evt->name = "msm_timer";
- evt->features = CLOCK_EVT_FEAT_ONESHOT;
- evt->rating = 200;
- evt->set_mode = msm_timer_set_mode;
- evt->set_next_event = msm_timer_set_next_event;
- evt->cpumask = cpumask_of(cpu);
-
- clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
-
- if (msm_timer_has_ppi) {
- enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
- } else {
- err = request_irq(evt->irq, msm_timer_interrupt,
- IRQF_TIMER | IRQF_NOBALANCING |
- IRQF_TRIGGER_RISING, "gp_timer", evt);
- if (err)
- pr_err("request_irq failed\n");
- }
-
- return 0;
-}
-
-static void msm_local_timer_stop(struct clock_event_device *evt)
-{
- evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
- disable_percpu_irq(evt->irq);
-}
-
-static int msm_timer_cpu_notify(struct notifier_block *self,
- unsigned long action, void *hcpu)
-{
- /*
- * Grab cpu pointer in each case to avoid spurious
- * preemptible warnings
- */
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_STARTING:
- msm_local_timer_setup(this_cpu_ptr(msm_evt));
- break;
- case CPU_DYING:
- msm_local_timer_stop(this_cpu_ptr(msm_evt));
- break;
- }
-
- return NOTIFY_OK;
-}
-
-static struct notifier_block msm_timer_cpu_nb = {
- .notifier_call = msm_timer_cpu_notify,
-};
-
-static u64 notrace msm_sched_clock_read(void)
-{
- return msm_clocksource.read(&msm_clocksource);
-}
-
-static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
- bool percpu)
-{
- struct clocksource *cs = &msm_clocksource;
- int res = 0;
-
- msm_timer_irq = irq;
- msm_timer_has_ppi = percpu;
-
- msm_evt = alloc_percpu(struct clock_event_device);
- if (!msm_evt) {
- pr_err("memory allocation failed for clockevents\n");
- goto err;
- }
-
- if (percpu)
- res = request_percpu_irq(irq, msm_timer_interrupt,
- "gp_timer", msm_evt);
-
- if (res) {
- pr_err("request_percpu_irq failed\n");
- } else {
- res = register_cpu_notifier(&msm_timer_cpu_nb);
- if (res) {
- free_percpu_irq(irq, msm_evt);
- goto err;
- }
-
- /* Immediately configure the timer on the boot CPU */
- msm_local_timer_setup(__this_cpu_ptr(msm_evt));
- }
-
-err:
- writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
- res = clocksource_register_hz(cs, dgt_hz);
- if (res)
- pr_err("clocksource_register failed\n");
- sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
-}
-
-#ifdef CONFIG_OF
-static void __init msm_dt_timer_init(struct device_node *np)
-{
- u32 freq;
- int irq;
- struct resource res;
- u32 percpu_offset;
- void __iomem *base;
- void __iomem *cpu0_base;
-
- base = of_iomap(np, 0);
- if (!base) {
- pr_err("Failed to map event base\n");
- return;
- }
-
- /* We use GPT0 for the clockevent */
- irq = irq_of_parse_and_map(np, 1);
- if (irq <= 0) {
- pr_err("Can't get irq\n");
- return;
- }
-
- /* We use CPU0's DGT for the clocksource */
- if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
- percpu_offset = 0;
-
- if (of_address_to_resource(np, 0, &res)) {
- pr_err("Failed to parse DGT resource\n");
- return;
- }
-
- cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
- if (!cpu0_base) {
- pr_err("Failed to map source base\n");
- return;
- }
-
- if (of_property_read_u32(np, "clock-frequency", &freq)) {
- pr_err("Unknown frequency\n");
- return;
- }
-
- event_base = base + 0x4;
- sts_base = base + 0x88;
- source_base = cpu0_base + 0x24;
- freq /= 4;
- writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
-
- msm_timer_init(freq, 32, irq, !!percpu_offset);
-}
-CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
-CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
-#endif
-
-static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
- u32 sts)
-{
- void __iomem *base;
-
- base = ioremap(addr, SZ_256);
- if (!base) {
- pr_err("Failed to map timer base\n");
- return -ENOMEM;
- }
- event_base = base + event;
- source_base = base + source;
- if (sts)
- sts_base = base + sts;
-
- return 0;
-}
-
-void __init msm7x01_timer_init(void)
-{
- struct clocksource *cs = &msm_clocksource;
-
- if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
- return;
- cs->read = msm_read_timer_count_shift;
- cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
- /* 600 KHz */
- msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
- false);
-}
-
-void __init msm7x30_timer_init(void)
-{
- if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
- return;
- msm_timer_init(24576000 / 4, 32, 1, false);
-}
-
-void __init qsd8x50_timer_init(void)
-{
- if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
- return;
- msm_timer_init(19200000 / 4, 32, 7, false);
-}
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cd6950f..81caa16 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -140,3 +140,7 @@ config VF_PIT_TIMER
bool
help
Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
+
+config CLKSRC_QCOM
+ bool
+ depends on ARCH_MSM
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index c7ca50a..2e0c0cc 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
+obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c
new file mode 100644
index 0000000..dca829e
--- /dev/null
+++ b/drivers/clocksource/qcom-timer.c
@@ -0,0 +1,329 @@
+/*
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009-2012,2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+#define TIMER_MATCH_VAL 0x0000
+#define TIMER_COUNT_VAL 0x0004
+#define TIMER_ENABLE 0x0008
+#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1)
+#define TIMER_ENABLE_EN BIT(0)
+#define TIMER_CLEAR 0x000C
+#define DGT_CLK_CTL 0x10
+#define DGT_CLK_CTL_DIV_4 0x3
+#define TIMER_STS_GPT0_CLR_PEND BIT(10)
+
+#define GPT_HZ 32768
+
+#define MSM_DGT_SHIFT 5
+
+static void __iomem *event_base;
+static void __iomem *sts_base;
+
+static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+ /* Stop the timer tick */
+ if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
+ u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
+ ctrl &= ~TIMER_ENABLE_EN;
+ writel_relaxed(ctrl, event_base + TIMER_ENABLE);
+ }
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static int msm_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
+
+ ctrl &= ~TIMER_ENABLE_EN;
+ writel_relaxed(ctrl, event_base + TIMER_ENABLE);
+
+ writel_relaxed(ctrl, event_base + TIMER_CLEAR);
+ writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
+
+ if (sts_base)
+ while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
+ cpu_relax();
+
+ writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
+ return 0;
+}
+
+static void msm_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 ctrl;
+
+ ctrl = readl_relaxed(event_base + TIMER_ENABLE);
+ ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_RESUME:
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Timer is enabled in set_next_event */
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+ }
+ writel_relaxed(ctrl, event_base + TIMER_ENABLE);
+}
+
+static struct clock_event_device __percpu *msm_evt;
+
+static void __iomem *source_base;
+
+static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
+{
+ return readl_relaxed(source_base + TIMER_COUNT_VAL);
+}
+
+static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
+{
+ /*
+ * Shift timer count down by a constant due to unreliable lower bits
+ * on some targets.
+ */
+ return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
+}
+
+static struct clocksource msm_clocksource = {
+ .name = "dg_timer",
+ .rating = 300,
+ .read = msm_read_timer_count,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int msm_timer_irq;
+static int msm_timer_has_ppi;
+
+static int msm_local_timer_setup(struct clock_event_device *evt)
+{
+ int cpu = smp_processor_id();
+ int err;
+
+ evt->irq = msm_timer_irq;
+ evt->name = "msm_timer";
+ evt->features = CLOCK_EVT_FEAT_ONESHOT;
+ evt->rating = 200;
+ evt->set_mode = msm_timer_set_mode;
+ evt->set_next_event = msm_timer_set_next_event;
+ evt->cpumask = cpumask_of(cpu);
+
+ clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
+
+ if (msm_timer_has_ppi) {
+ enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
+ } else {
+ err = request_irq(evt->irq, msm_timer_interrupt,
+ IRQF_TIMER | IRQF_NOBALANCING |
+ IRQF_TRIGGER_RISING, "gp_timer", evt);
+ if (err)
+ pr_err("request_irq failed\n");
+ }
+
+ return 0;
+}
+
+static void msm_local_timer_stop(struct clock_event_device *evt)
+{
+ evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+ disable_percpu_irq(evt->irq);
+}
+
+static int msm_timer_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ /*
+ * Grab cpu pointer in each case to avoid spurious
+ * preemptible warnings
+ */
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_STARTING:
+ msm_local_timer_setup(this_cpu_ptr(msm_evt));
+ break;
+ case CPU_DYING:
+ msm_local_timer_stop(this_cpu_ptr(msm_evt));
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block msm_timer_cpu_nb = {
+ .notifier_call = msm_timer_cpu_notify,
+};
+
+static u64 notrace msm_sched_clock_read(void)
+{
+ return msm_clocksource.read(&msm_clocksource);
+}
+
+static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
+ bool percpu)
+{
+ struct clocksource *cs = &msm_clocksource;
+ int res = 0;
+
+ msm_timer_irq = irq;
+ msm_timer_has_ppi = percpu;
+
+ msm_evt = alloc_percpu(struct clock_event_device);
+ if (!msm_evt) {
+ pr_err("memory allocation failed for clockevents\n");
+ goto err;
+ }
+
+ if (percpu)
+ res = request_percpu_irq(irq, msm_timer_interrupt,
+ "gp_timer", msm_evt);
+
+ if (res) {
+ pr_err("request_percpu_irq failed\n");
+ } else {
+ res = register_cpu_notifier(&msm_timer_cpu_nb);
+ if (res) {
+ free_percpu_irq(irq, msm_evt);
+ goto err;
+ }
+
+ /* Immediately configure the timer on the boot CPU */
+ msm_local_timer_setup(__this_cpu_ptr(msm_evt));
+ }
+
+err:
+ writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
+ res = clocksource_register_hz(cs, dgt_hz);
+ if (res)
+ pr_err("clocksource_register failed\n");
+ sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
+}
+
+#ifdef CONFIG_OF
+static void __init msm_dt_timer_init(struct device_node *np)
+{
+ u32 freq;
+ int irq;
+ struct resource res;
+ u32 percpu_offset;
+ void __iomem *base;
+ void __iomem *cpu0_base;
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_err("Failed to map event base\n");
+ return;
+ }
+
+ /* We use GPT0 for the clockevent */
+ irq = irq_of_parse_and_map(np, 1);
+ if (irq <= 0) {
+ pr_err("Can't get irq\n");
+ return;
+ }
+
+ /* We use CPU0's DGT for the clocksource */
+ if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
+ percpu_offset = 0;
+
+ if (of_address_to_resource(np, 0, &res)) {
+ pr_err("Failed to parse DGT resource\n");
+ return;
+ }
+
+ cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
+ if (!cpu0_base) {
+ pr_err("Failed to map source base\n");
+ return;
+ }
+
+ if (of_property_read_u32(np, "clock-frequency", &freq)) {
+ pr_err("Unknown frequency\n");
+ return;
+ }
+
+ event_base = base + 0x4;
+ sts_base = base + 0x88;
+ source_base = cpu0_base + 0x24;
+ freq /= 4;
+ writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
+
+ msm_timer_init(freq, 32, irq, !!percpu_offset);
+}
+CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
+CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
+#endif
+
+static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
+ u32 sts)
+{
+ void __iomem *base;
+
+ base = ioremap(addr, SZ_256);
+ if (!base) {
+ pr_err("Failed to map timer base\n");
+ return -ENOMEM;
+ }
+ event_base = base + event;
+ source_base = base + source;
+ if (sts)
+ sts_base = base + sts;
+
+ return 0;
+}
+
+void __init msm7x01_timer_init(void)
+{
+ struct clocksource *cs = &msm_clocksource;
+
+ if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
+ return;
+ cs->read = msm_read_timer_count_shift;
+ cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
+ /* 600 KHz */
+ msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
+ false);
+}
+
+void __init msm7x30_timer_init(void)
+{
+ if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
+ return;
+ msm_timer_init(24576000 / 4, 32, 1, false);
+}
+
+void __init qsd8x50_timer_init(void)
+{
+ if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
+ return;
+ msm_timer_init(19200000 / 4, 32, 7, false);
+}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH 3/5] arm: qcom: Split Qualcomm support into legacy and multiplatform
From: Kumar Gala @ 2014-02-04 22:37 UTC (permalink / raw)
To: linux-arm-kernel
Introduce a new mach-qcom that will support SoCs that intend to be
multiplatform compatiable while keeping mach-msm to legacy SoC/board
support that will not transition over to multiplatform.
As part of this, we move support for MSM8X60, MSM8960 and MSM8974 over
to mach-qcom.
Signed-off-by: Kumar Gala <galak@codeaurora.org>
---
MAINTAINERS | 8 ++
arch/arm/Kconfig | 7 +-
arch/arm/Kconfig.debug | 2 +-
arch/arm/Makefile | 1 +
arch/arm/boot/dts/Makefile | 6 +-
arch/arm/mach-msm/Kconfig | 45 +------
arch/arm/mach-msm/Makefile | 6 -
arch/arm/mach-msm/board-dt.c | 41 ------
arch/arm/mach-msm/platsmp.c | 137 -------------------
arch/arm/mach-msm/scm-boot.c | 39 ------
arch/arm/mach-msm/scm-boot.h | 22 ----
arch/arm/mach-msm/scm.c | 299 ------------------------------------------
arch/arm/mach-msm/scm.h | 25 ----
arch/arm/mach-qcom/Kconfig | 33 +++++
arch/arm/mach-qcom/Makefile | 5 +
arch/arm/mach-qcom/board.c | 40 ++++++
arch/arm/mach-qcom/scm-boot.c | 39 ++++++
arch/arm/mach-qcom/scm-boot.h | 22 ++++
arch/arm/mach-qcom/scm.c | 299 ++++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-qcom/scm.h | 25 ++++
arch/arm/mach-qcom/smp.c | 137 +++++++++++++++++++
21 files changed, 619 insertions(+), 619 deletions(-)
delete mode 100644 arch/arm/mach-msm/board-dt.c
delete mode 100644 arch/arm/mach-msm/platsmp.c
delete mode 100644 arch/arm/mach-msm/scm-boot.c
delete mode 100644 arch/arm/mach-msm/scm-boot.h
delete mode 100644 arch/arm/mach-msm/scm.c
delete mode 100644 arch/arm/mach-msm/scm.h
create mode 100644 arch/arm/mach-qcom/Kconfig
create mode 100644 arch/arm/mach-qcom/Makefile
create mode 100644 arch/arm/mach-qcom/board.c
create mode 100644 arch/arm/mach-qcom/scm-boot.c
create mode 100644 arch/arm/mach-qcom/scm-boot.h
create mode 100644 arch/arm/mach-qcom/scm.c
create mode 100644 arch/arm/mach-qcom/scm.h
create mode 100644 arch/arm/mach-qcom/smp.c
diff --git a/MAINTAINERS b/MAINTAINERS
index b2cf5cf..402be60 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1167,6 +1167,14 @@ L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
W: http://www.arm.linux.org.uk/
S: Maintained
+ARM/QUALCOMM SUPPORT
+M: Kumar Gala <galak@codeaurora.org>
+M: David Brown <davidb@codeaurora.org>
+L: linux-arm-msm at vger.kernel.org
+S: Maintained
+F: arch/arm/mach-qcom/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
+
ARM/RADISYS ENP2611 MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e254198..f093f20 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -657,9 +657,8 @@ config ARCH_PXA
help
Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
-config ARCH_MSM_NODT
- bool "Qualcomm MSM"
- select ARCH_MSM
+config ARCH_MSM
+ bool "Qualcomm MSM (non-multiplatform)"
select ARCH_REQUIRE_GPIOLIB
select COMMON_CLK
select GENERIC_CLOCKEVENTS
@@ -1005,6 +1004,8 @@ source "arch/arm/plat-pxa/Kconfig"
source "arch/arm/mach-mmp/Kconfig"
+source "arch/arm/mach-qcom/Kconfig"
+
source "arch/arm/mach-realview/Kconfig"
source "arch/arm/mach-rockchip/Kconfig"
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 0531da8..4491c7b 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -956,7 +956,7 @@ config DEBUG_STI_UART
config DEBUG_MSM_UART
bool
- depends on ARCH_MSM
+ depends on ARCH_MSM || ARCH_QCOM
config DEBUG_LL_INCLUDE
string
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 08a9ef5..51e5bed 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -180,6 +180,7 @@ machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2
machine-$(CONFIG_ARCH_ORION5X) += orion5x
machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell
machine-$(CONFIG_ARCH_PXA) += pxa
+machine-$(CONFIG_ARCH_QCOM) += qcom
machine-$(CONFIG_ARCH_REALVIEW) += realview
machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip
machine-$(CONFIG_ARCH_RPC) += rpc
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b9d6a8b..c9eaf1f 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -118,9 +118,6 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
kirkwood-ts219-6282.dtb
dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
-dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \
- qcom-msm8960-cdp.dtb \
- qcom-apq8074-dragonboard.dtb
dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
armada-370-mirabox.dtb \
armada-370-netgear-rn102.dtb \
@@ -232,6 +229,9 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
dra7-evm.dtb
dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
+ qcom-msm8960-cdp.dtb \
+ qcom-apq8074-dragonboard.dtb
dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
ste-hrefprev60-stuib.dtb \
ste-hrefprev60-tvk.dtb \
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 3c4eca7..a7f959e 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1,50 +1,9 @@
-config ARCH_MSM
- bool
-
-config ARCH_MSM_DT
- bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7
- select ARCH_MSM
- select ARCH_REQUIRE_GPIOLIB
- select CLKSRC_OF
- select GENERIC_CLOCKEVENTS
- help
- Support for Qualcomm's devicetree based MSM systems.
-
if ARCH_MSM
-menu "Qualcomm MSM SoC Selection"
- depends on ARCH_MSM_DT
-
-config ARCH_MSM8X60
- bool "Enable support for MSM8X60"
- select ARM_GIC
- select CPU_V7
- select HAVE_SMP
- select MSM_SCM if SMP
- select CLKSRC_QCOM
-
-config ARCH_MSM8960
- bool "Enable support for MSM8960"
- select ARM_GIC
- select CPU_V7
- select HAVE_SMP
- select MSM_SCM if SMP
- select CLKSRC_QCOM
-
-config ARCH_MSM8974
- bool "Enable support for MSM8974"
- select ARM_GIC
- select CPU_V7
- select HAVE_ARM_ARCH_TIMER
- select HAVE_SMP
- select MSM_SCM if SMP
-
-endmenu
-
choice
prompt "Qualcomm MSM SoC Type"
default ARCH_MSM7X00A
- depends on ARCH_MSM_NODT
+ depends on ARCH_MSM
config ARCH_MSM7X00A
bool "MSM7x00A / MSM7x01A"
@@ -99,7 +58,7 @@ config MSM_VIC
bool
menu "Qualcomm MSM Board Type"
- depends on ARCH_MSM_NODT
+ depends on ARCH_MSM
config MACH_HALIBUT
depends on ARCH_MSM
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 04b1bee..27c078a 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -13,17 +13,11 @@ obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o
obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
obj-$(CONFIG_MSM_SMD) += last_radio_log.o
-obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
-
-CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
-
-obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
-obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o
obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
deleted file mode 100644
index 1f11d93..0000000
--- a/arch/arm/mach-msm/board-dt.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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.
- */
-
-#include <linux/init.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-
-static const char * const msm_dt_match[] __initconst = {
- "qcom,msm8660-fluid",
- "qcom,msm8660-surf",
- "qcom,msm8960-cdp",
- NULL
-};
-
-static const char * const apq8074_dt_match[] __initconst = {
- "qcom,apq8074-dragonboard",
- NULL
-};
-
-DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
- .smp = smp_ops(msm_smp_ops),
- .dt_compat = msm_dt_match,
-MACHINE_END
-
-DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)")
- .dt_compat = apq8074_dt_match,
-MACHINE_END
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
deleted file mode 100644
index 251a91e..0000000
--- a/arch/arm/mach-msm/platsmp.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2002 ARM Ltd.
- * All Rights Reserved
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-
-#include <asm/cputype.h>
-#include <asm/smp_plat.h>
-
-#include "scm-boot.h"
-#include "common.h"
-
-#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
-#define SCSS_CPU1CORE_RESET 0xD80
-#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
-
-extern void secondary_startup(void);
-
-static DEFINE_SPINLOCK(boot_lock);
-
-#ifdef CONFIG_HOTPLUG_CPU
-static void __ref msm_cpu_die(unsigned int cpu)
-{
- wfi();
-}
-#endif
-
-static inline int get_core_count(void)
-{
- /* 1 + the PART[1:0] field of MIDR */
- return ((read_cpuid_id() >> 4) & 3) + 1;
-}
-
-static void msm_secondary_init(unsigned int cpu)
-{
- /*
- * Synchronise with the boot thread.
- */
- spin_lock(&boot_lock);
- spin_unlock(&boot_lock);
-}
-
-static void prepare_cold_cpu(unsigned int cpu)
-{
- int ret;
- ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
- SCM_FLAG_COLDBOOT_CPU1);
- if (ret == 0) {
- void __iomem *sc1_base_ptr;
- sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
- if (sc1_base_ptr) {
- writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
- writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
- writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
- iounmap(sc1_base_ptr);
- }
- } else
- printk(KERN_DEBUG "Failed to set secondary core boot "
- "address\n");
-}
-
-static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
- static int cold_boot_done;
-
- /* Only need to bring cpu out of reset this way once */
- if (cold_boot_done == false) {
- prepare_cold_cpu(cpu);
- cold_boot_done = true;
- }
-
- /*
- * set synchronisation state between this boot processor
- * and the secondary one
- */
- spin_lock(&boot_lock);
-
- /*
- * Send the secondary CPU a soft interrupt, thereby causing
- * the boot monitor to read the system wide flags register,
- * and branch to the address found there.
- */
- arch_send_wakeup_ipi_mask(cpumask_of(cpu));
-
- /*
- * now the secondary core is starting up let it run its
- * calibrations, then wait for it to finish
- */
- spin_unlock(&boot_lock);
-
- return 0;
-}
-
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system. The msm8x60
- * does not support the ARM SCU, so just set the possible cpu mask to
- * NR_CPUS.
- */
-static void __init msm_smp_init_cpus(void)
-{
- unsigned int i, ncores = get_core_count();
-
- if (ncores > nr_cpu_ids) {
- pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
- ncores, nr_cpu_ids);
- ncores = nr_cpu_ids;
- }
-
- for (i = 0; i < ncores; i++)
- set_cpu_possible(i, true);
-}
-
-static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
-{
-}
-
-struct smp_operations msm_smp_ops __initdata = {
- .smp_init_cpus = msm_smp_init_cpus,
- .smp_prepare_cpus = msm_smp_prepare_cpus,
- .smp_secondary_init = msm_secondary_init,
- .smp_boot_secondary = msm_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
- .cpu_die = msm_cpu_die,
-#endif
-};
diff --git a/arch/arm/mach-msm/scm-boot.c b/arch/arm/mach-msm/scm-boot.c
deleted file mode 100644
index 45cee3e..0000000
--- a/arch/arm/mach-msm/scm-boot.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "scm.h"
-#include "scm-boot.h"
-
-/*
- * Set the cold/warm boot address for one of the CPU cores.
- */
-int scm_set_boot_addr(phys_addr_t addr, int flags)
-{
- struct {
- unsigned int flags;
- phys_addr_t addr;
- } cmd;
-
- cmd.addr = addr;
- cmd.flags = flags;
- return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
- &cmd, sizeof(cmd), NULL, 0);
-}
-EXPORT_SYMBOL(scm_set_boot_addr);
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
deleted file mode 100644
index 7be32ff..0000000
--- a/arch/arm/mach-msm/scm-boot.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef __MACH_SCM_BOOT_H
-#define __MACH_SCM_BOOT_H
-
-#define SCM_BOOT_ADDR 0x1
-#define SCM_FLAG_COLDBOOT_CPU1 0x1
-#define SCM_FLAG_WARMBOOT_CPU1 0x2
-#define SCM_FLAG_WARMBOOT_CPU0 0x4
-
-int scm_set_boot_addr(phys_addr_t addr, int flags);
-
-#endif
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
deleted file mode 100644
index c536fd6..0000000
--- a/arch/arm/mach-msm/scm.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-
-#include <asm/cacheflush.h>
-
-#include "scm.h"
-
-/* Cache line size for msm8x60 */
-#define CACHELINESIZE 32
-
-#define SCM_ENOMEM -5
-#define SCM_EOPNOTSUPP -4
-#define SCM_EINVAL_ADDR -3
-#define SCM_EINVAL_ARG -2
-#define SCM_ERROR -1
-#define SCM_INTERRUPTED 1
-
-static DEFINE_MUTEX(scm_lock);
-
-/**
- * struct scm_command - one SCM command buffer
- * @len: total available memory for command and response
- * @buf_offset: start of command buffer
- * @resp_hdr_offset: start of response buffer
- * @id: command to be executed
- * @buf: buffer returned from scm_get_command_buffer()
- *
- * An SCM command is laid out in memory as follows:
- *
- * ------------------- <--- struct scm_command
- * | command header |
- * ------------------- <--- scm_get_command_buffer()
- * | command buffer |
- * ------------------- <--- struct scm_response and
- * | response header | scm_command_to_response()
- * ------------------- <--- scm_get_response_buffer()
- * | response buffer |
- * -------------------
- *
- * There can be arbitrary padding between the headers and buffers so
- * you should always use the appropriate scm_get_*_buffer() routines
- * to access the buffers in a safe manner.
- */
-struct scm_command {
- u32 len;
- u32 buf_offset;
- u32 resp_hdr_offset;
- u32 id;
- u32 buf[0];
-};
-
-/**
- * struct scm_response - one SCM response buffer
- * @len: total available memory for response
- * @buf_offset: start of response data relative to start of scm_response
- * @is_complete: indicates if the command has finished processing
- */
-struct scm_response {
- u32 len;
- u32 buf_offset;
- u32 is_complete;
-};
-
-/**
- * alloc_scm_command() - Allocate an SCM command
- * @cmd_size: size of the command buffer
- * @resp_size: size of the response buffer
- *
- * Allocate an SCM command, including enough room for the command
- * and response headers as well as the command and response buffers.
- *
- * Returns a valid &scm_command on success or %NULL if the allocation fails.
- */
-static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
-{
- struct scm_command *cmd;
- size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
- resp_size;
-
- cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
- if (cmd) {
- cmd->len = len;
- cmd->buf_offset = offsetof(struct scm_command, buf);
- cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
- }
- return cmd;
-}
-
-/**
- * free_scm_command() - Free an SCM command
- * @cmd: command to free
- *
- * Free an SCM command.
- */
-static inline void free_scm_command(struct scm_command *cmd)
-{
- kfree(cmd);
-}
-
-/**
- * scm_command_to_response() - Get a pointer to a scm_response
- * @cmd: command
- *
- * Returns a pointer to a response for a command.
- */
-static inline struct scm_response *scm_command_to_response(
- const struct scm_command *cmd)
-{
- return (void *)cmd + cmd->resp_hdr_offset;
-}
-
-/**
- * scm_get_command_buffer() - Get a pointer to a command buffer
- * @cmd: command
- *
- * Returns a pointer to the command buffer of a command.
- */
-static inline void *scm_get_command_buffer(const struct scm_command *cmd)
-{
- return (void *)cmd->buf;
-}
-
-/**
- * scm_get_response_buffer() - Get a pointer to a response buffer
- * @rsp: response
- *
- * Returns a pointer to a response buffer of a response.
- */
-static inline void *scm_get_response_buffer(const struct scm_response *rsp)
-{
- return (void *)rsp + rsp->buf_offset;
-}
-
-static int scm_remap_error(int err)
-{
- switch (err) {
- case SCM_ERROR:
- return -EIO;
- case SCM_EINVAL_ADDR:
- case SCM_EINVAL_ARG:
- return -EINVAL;
- case SCM_EOPNOTSUPP:
- return -EOPNOTSUPP;
- case SCM_ENOMEM:
- return -ENOMEM;
- }
- return -EINVAL;
-}
-
-static u32 smc(u32 cmd_addr)
-{
- int context_id;
- register u32 r0 asm("r0") = 1;
- register u32 r1 asm("r1") = (u32)&context_id;
- register u32 r2 asm("r2") = cmd_addr;
- do {
- asm volatile(
- __asmeq("%0", "r0")
- __asmeq("%1", "r0")
- __asmeq("%2", "r1")
- __asmeq("%3", "r2")
-#ifdef REQUIRES_SEC
- ".arch_extension sec\n"
-#endif
- "smc #0 @ switch to secure world\n"
- : "=r" (r0)
- : "r" (r0), "r" (r1), "r" (r2)
- : "r3");
- } while (r0 == SCM_INTERRUPTED);
-
- return r0;
-}
-
-static int __scm_call(const struct scm_command *cmd)
-{
- int ret;
- u32 cmd_addr = virt_to_phys(cmd);
-
- /*
- * Flush the entire cache here so callers don't have to remember
- * to flush the cache when passing physical addresses to the secure
- * side in the buffer.
- */
- flush_cache_all();
- ret = smc(cmd_addr);
- if (ret < 0)
- ret = scm_remap_error(ret);
-
- return ret;
-}
-
-/**
- * scm_call() - Send an SCM command
- * @svc_id: service identifier
- * @cmd_id: command identifier
- * @cmd_buf: command buffer
- * @cmd_len: length of the command buffer
- * @resp_buf: response buffer
- * @resp_len: length of the response buffer
- *
- * Sends a command to the SCM and waits for the command to finish processing.
- */
-int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
- void *resp_buf, size_t resp_len)
-{
- int ret;
- struct scm_command *cmd;
- struct scm_response *rsp;
-
- cmd = alloc_scm_command(cmd_len, resp_len);
- if (!cmd)
- return -ENOMEM;
-
- cmd->id = (svc_id << 10) | cmd_id;
- if (cmd_buf)
- memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
-
- mutex_lock(&scm_lock);
- ret = __scm_call(cmd);
- mutex_unlock(&scm_lock);
- if (ret)
- goto out;
-
- rsp = scm_command_to_response(cmd);
- do {
- u32 start = (u32)rsp;
- u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
- start &= ~(CACHELINESIZE - 1);
- while (start < end) {
- asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
- : "memory");
- start += CACHELINESIZE;
- }
- } while (!rsp->is_complete);
-
- if (resp_buf)
- memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
-out:
- free_scm_command(cmd);
- return ret;
-}
-EXPORT_SYMBOL(scm_call);
-
-u32 scm_get_version(void)
-{
- int context_id;
- static u32 version = -1;
- register u32 r0 asm("r0");
- register u32 r1 asm("r1");
-
- if (version != -1)
- return version;
-
- mutex_lock(&scm_lock);
-
- r0 = 0x1 << 8;
- r1 = (u32)&context_id;
- do {
- asm volatile(
- __asmeq("%0", "r0")
- __asmeq("%1", "r1")
- __asmeq("%2", "r0")
- __asmeq("%3", "r1")
-#ifdef REQUIRES_SEC
- ".arch_extension sec\n"
-#endif
- "smc #0 @ switch to secure world\n"
- : "=r" (r0), "=r" (r1)
- : "r" (r0), "r" (r1)
- : "r2", "r3");
- } while (r0 == SCM_INTERRUPTED);
-
- version = r1;
- mutex_unlock(&scm_lock);
-
- return version;
-}
-EXPORT_SYMBOL(scm_get_version);
diff --git a/arch/arm/mach-msm/scm.h b/arch/arm/mach-msm/scm.h
deleted file mode 100644
index 00b31ea..0000000
--- a/arch/arm/mach-msm/scm.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef __MACH_SCM_H
-#define __MACH_SCM_H
-
-#define SCM_SVC_BOOT 0x1
-#define SCM_SVC_PIL 0x2
-
-extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
- void *resp_buf, size_t resp_len);
-
-#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
-
-extern u32 scm_get_version(void);
-
-#endif
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
new file mode 100644
index 0000000..755b0db
--- /dev/null
+++ b/arch/arm/mach-qcom/Kconfig
@@ -0,0 +1,33 @@
+config ARCH_QCOM
+ bool "Qualcomm Support" if ARCH_MULTI_V7
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKSRC_OF
+ select GENERIC_CLOCKEVENTS
+ select ARM_GIC
+ select HAVE_SMP
+ select QCOM_SCM if SMP
+ help
+ Support for Qualcomm's devicetree based systems.
+
+if ARCH_QCOM
+
+menu "Qualcomm SoC Selection"
+
+config ARCH_MSM8X60
+ bool "Enable support for MSM8X60"
+ select CLKSRC_QCOM
+
+config ARCH_MSM8960
+ bool "Enable support for MSM8960"
+ select CLKSRC_QCOM
+
+config ARCH_MSM8974
+ bool "Enable support for MSM8974"
+ select HAVE_ARM_ARCH_TIMER
+
+endmenu
+
+config QCOM_SCM
+ bool
+
+endif
diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
new file mode 100644
index 0000000..c0ba0ef
--- /dev/null
+++ b/arch/arm/mach-qcom/Makefile
@@ -0,0 +1,5 @@
+obj-y := board.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
+
+CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
new file mode 100644
index 0000000..4529f6b
--- /dev/null
+++ b/arch/arm/mach-qcom/board.c
@@ -0,0 +1,40 @@
+/* Copyright (c) 2010-2014 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+extern struct smp_operations msm_smp_ops;
+
+static const char * const qcom_dt_match[] __initconst = {
+ "qcom,msm8660-surf",
+ "qcom,msm8960-cdp",
+ NULL
+};
+
+static const char * const apq8074_dt_match[] __initconst = {
+ "qcom,apq8074-dragonboard",
+ NULL
+};
+
+DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
+ .smp = smp_ops(msm_smp_ops),
+ .dt_compat = qcom_dt_match,
+MACHINE_END
+
+DT_MACHINE_START(APQ_DT, "Qualcomm (Flattened Device Tree)")
+ .dt_compat = apq8074_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-qcom/scm-boot.c b/arch/arm/mach-qcom/scm-boot.c
new file mode 100644
index 0000000..45cee3e
--- /dev/null
+++ b/arch/arm/mach-qcom/scm-boot.c
@@ -0,0 +1,39 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "scm.h"
+#include "scm-boot.h"
+
+/*
+ * Set the cold/warm boot address for one of the CPU cores.
+ */
+int scm_set_boot_addr(phys_addr_t addr, int flags)
+{
+ struct {
+ unsigned int flags;
+ phys_addr_t addr;
+ } cmd;
+
+ cmd.addr = addr;
+ cmd.flags = flags;
+ return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
+ &cmd, sizeof(cmd), NULL, 0);
+}
+EXPORT_SYMBOL(scm_set_boot_addr);
diff --git a/arch/arm/mach-qcom/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
new file mode 100644
index 0000000..7be32ff
--- /dev/null
+++ b/arch/arm/mach-qcom/scm-boot.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#ifndef __MACH_SCM_BOOT_H
+#define __MACH_SCM_BOOT_H
+
+#define SCM_BOOT_ADDR 0x1
+#define SCM_FLAG_COLDBOOT_CPU1 0x1
+#define SCM_FLAG_WARMBOOT_CPU1 0x2
+#define SCM_FLAG_WARMBOOT_CPU0 0x4
+
+int scm_set_boot_addr(phys_addr_t addr, int flags);
+
+#endif
diff --git a/arch/arm/mach-qcom/scm.c b/arch/arm/mach-qcom/scm.c
new file mode 100644
index 0000000..c536fd6
--- /dev/null
+++ b/arch/arm/mach-qcom/scm.c
@@ -0,0 +1,299 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/cacheflush.h>
+
+#include "scm.h"
+
+/* Cache line size for msm8x60 */
+#define CACHELINESIZE 32
+
+#define SCM_ENOMEM -5
+#define SCM_EOPNOTSUPP -4
+#define SCM_EINVAL_ADDR -3
+#define SCM_EINVAL_ARG -2
+#define SCM_ERROR -1
+#define SCM_INTERRUPTED 1
+
+static DEFINE_MUTEX(scm_lock);
+
+/**
+ * struct scm_command - one SCM command buffer
+ * @len: total available memory for command and response
+ * @buf_offset: start of command buffer
+ * @resp_hdr_offset: start of response buffer
+ * @id: command to be executed
+ * @buf: buffer returned from scm_get_command_buffer()
+ *
+ * An SCM command is laid out in memory as follows:
+ *
+ * ------------------- <--- struct scm_command
+ * | command header |
+ * ------------------- <--- scm_get_command_buffer()
+ * | command buffer |
+ * ------------------- <--- struct scm_response and
+ * | response header | scm_command_to_response()
+ * ------------------- <--- scm_get_response_buffer()
+ * | response buffer |
+ * -------------------
+ *
+ * There can be arbitrary padding between the headers and buffers so
+ * you should always use the appropriate scm_get_*_buffer() routines
+ * to access the buffers in a safe manner.
+ */
+struct scm_command {
+ u32 len;
+ u32 buf_offset;
+ u32 resp_hdr_offset;
+ u32 id;
+ u32 buf[0];
+};
+
+/**
+ * struct scm_response - one SCM response buffer
+ * @len: total available memory for response
+ * @buf_offset: start of response data relative to start of scm_response
+ * @is_complete: indicates if the command has finished processing
+ */
+struct scm_response {
+ u32 len;
+ u32 buf_offset;
+ u32 is_complete;
+};
+
+/**
+ * alloc_scm_command() - Allocate an SCM command
+ * @cmd_size: size of the command buffer
+ * @resp_size: size of the response buffer
+ *
+ * Allocate an SCM command, including enough room for the command
+ * and response headers as well as the command and response buffers.
+ *
+ * Returns a valid &scm_command on success or %NULL if the allocation fails.
+ */
+static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
+{
+ struct scm_command *cmd;
+ size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
+ resp_size;
+
+ cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
+ if (cmd) {
+ cmd->len = len;
+ cmd->buf_offset = offsetof(struct scm_command, buf);
+ cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
+ }
+ return cmd;
+}
+
+/**
+ * free_scm_command() - Free an SCM command
+ * @cmd: command to free
+ *
+ * Free an SCM command.
+ */
+static inline void free_scm_command(struct scm_command *cmd)
+{
+ kfree(cmd);
+}
+
+/**
+ * scm_command_to_response() - Get a pointer to a scm_response
+ * @cmd: command
+ *
+ * Returns a pointer to a response for a command.
+ */
+static inline struct scm_response *scm_command_to_response(
+ const struct scm_command *cmd)
+{
+ return (void *)cmd + cmd->resp_hdr_offset;
+}
+
+/**
+ * scm_get_command_buffer() - Get a pointer to a command buffer
+ * @cmd: command
+ *
+ * Returns a pointer to the command buffer of a command.
+ */
+static inline void *scm_get_command_buffer(const struct scm_command *cmd)
+{
+ return (void *)cmd->buf;
+}
+
+/**
+ * scm_get_response_buffer() - Get a pointer to a response buffer
+ * @rsp: response
+ *
+ * Returns a pointer to a response buffer of a response.
+ */
+static inline void *scm_get_response_buffer(const struct scm_response *rsp)
+{
+ return (void *)rsp + rsp->buf_offset;
+}
+
+static int scm_remap_error(int err)
+{
+ switch (err) {
+ case SCM_ERROR:
+ return -EIO;
+ case SCM_EINVAL_ADDR:
+ case SCM_EINVAL_ARG:
+ return -EINVAL;
+ case SCM_EOPNOTSUPP:
+ return -EOPNOTSUPP;
+ case SCM_ENOMEM:
+ return -ENOMEM;
+ }
+ return -EINVAL;
+}
+
+static u32 smc(u32 cmd_addr)
+{
+ int context_id;
+ register u32 r0 asm("r0") = 1;
+ register u32 r1 asm("r1") = (u32)&context_id;
+ register u32 r2 asm("r2") = cmd_addr;
+ do {
+ asm volatile(
+ __asmeq("%0", "r0")
+ __asmeq("%1", "r0")
+ __asmeq("%2", "r1")
+ __asmeq("%3", "r2")
+#ifdef REQUIRES_SEC
+ ".arch_extension sec\n"
+#endif
+ "smc #0 @ switch to secure world\n"
+ : "=r" (r0)
+ : "r" (r0), "r" (r1), "r" (r2)
+ : "r3");
+ } while (r0 == SCM_INTERRUPTED);
+
+ return r0;
+}
+
+static int __scm_call(const struct scm_command *cmd)
+{
+ int ret;
+ u32 cmd_addr = virt_to_phys(cmd);
+
+ /*
+ * Flush the entire cache here so callers don't have to remember
+ * to flush the cache when passing physical addresses to the secure
+ * side in the buffer.
+ */
+ flush_cache_all();
+ ret = smc(cmd_addr);
+ if (ret < 0)
+ ret = scm_remap_error(ret);
+
+ return ret;
+}
+
+/**
+ * scm_call() - Send an SCM command
+ * @svc_id: service identifier
+ * @cmd_id: command identifier
+ * @cmd_buf: command buffer
+ * @cmd_len: length of the command buffer
+ * @resp_buf: response buffer
+ * @resp_len: length of the response buffer
+ *
+ * Sends a command to the SCM and waits for the command to finish processing.
+ */
+int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
+ void *resp_buf, size_t resp_len)
+{
+ int ret;
+ struct scm_command *cmd;
+ struct scm_response *rsp;
+
+ cmd = alloc_scm_command(cmd_len, resp_len);
+ if (!cmd)
+ return -ENOMEM;
+
+ cmd->id = (svc_id << 10) | cmd_id;
+ if (cmd_buf)
+ memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
+
+ mutex_lock(&scm_lock);
+ ret = __scm_call(cmd);
+ mutex_unlock(&scm_lock);
+ if (ret)
+ goto out;
+
+ rsp = scm_command_to_response(cmd);
+ do {
+ u32 start = (u32)rsp;
+ u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
+ start &= ~(CACHELINESIZE - 1);
+ while (start < end) {
+ asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
+ : "memory");
+ start += CACHELINESIZE;
+ }
+ } while (!rsp->is_complete);
+
+ if (resp_buf)
+ memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
+out:
+ free_scm_command(cmd);
+ return ret;
+}
+EXPORT_SYMBOL(scm_call);
+
+u32 scm_get_version(void)
+{
+ int context_id;
+ static u32 version = -1;
+ register u32 r0 asm("r0");
+ register u32 r1 asm("r1");
+
+ if (version != -1)
+ return version;
+
+ mutex_lock(&scm_lock);
+
+ r0 = 0x1 << 8;
+ r1 = (u32)&context_id;
+ do {
+ asm volatile(
+ __asmeq("%0", "r0")
+ __asmeq("%1", "r1")
+ __asmeq("%2", "r0")
+ __asmeq("%3", "r1")
+#ifdef REQUIRES_SEC
+ ".arch_extension sec\n"
+#endif
+ "smc #0 @ switch to secure world\n"
+ : "=r" (r0), "=r" (r1)
+ : "r" (r0), "r" (r1)
+ : "r2", "r3");
+ } while (r0 == SCM_INTERRUPTED);
+
+ version = r1;
+ mutex_unlock(&scm_lock);
+
+ return version;
+}
+EXPORT_SYMBOL(scm_get_version);
diff --git a/arch/arm/mach-qcom/scm.h b/arch/arm/mach-qcom/scm.h
new file mode 100644
index 0000000..00b31ea
--- /dev/null
+++ b/arch/arm/mach-qcom/scm.h
@@ -0,0 +1,25 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#ifndef __MACH_SCM_H
+#define __MACH_SCM_H
+
+#define SCM_SVC_BOOT 0x1
+#define SCM_SVC_PIL 0x2
+
+extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
+ void *resp_buf, size_t resp_len);
+
+#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
+
+extern u32 scm_get_version(void);
+
+#endif
diff --git a/arch/arm/mach-qcom/smp.c b/arch/arm/mach-qcom/smp.c
new file mode 100644
index 0000000..67823a7
--- /dev/null
+++ b/arch/arm/mach-qcom/smp.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cputype.h>
+#include <asm/smp_plat.h>
+
+#include "scm-boot.h"
+
+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
+#define SCSS_CPU1CORE_RESET 0xD80
+#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
+
+extern void secondary_startup(void);
+
+static DEFINE_SPINLOCK(boot_lock);
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void __ref msm_cpu_die(unsigned int cpu)
+{
+ wfi();
+}
+#endif
+
+static inline int get_core_count(void)
+{
+ /* 1 + the PART[1:0] field of MIDR */
+ return ((read_cpuid_id() >> 4) & 3) + 1;
+}
+
+static void msm_secondary_init(unsigned int cpu)
+{
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+static void prepare_cold_cpu(unsigned int cpu)
+{
+ int ret;
+ ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
+ SCM_FLAG_COLDBOOT_CPU1);
+ if (ret == 0) {
+ void __iomem *sc1_base_ptr;
+ sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
+ if (sc1_base_ptr) {
+ writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
+ writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
+ writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
+ iounmap(sc1_base_ptr);
+ }
+ } else
+ printk(KERN_DEBUG "Failed to set secondary core boot "
+ "address\n");
+}
+
+static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ static int cold_boot_done;
+
+ /* Only need to bring cpu out of reset this way once */
+ if (cold_boot_done == false) {
+ prepare_cold_cpu(cpu);
+ cold_boot_done = true;
+ }
+
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * Send the secondary CPU a soft interrupt, thereby causing
+ * the boot monitor to read the system wide flags register,
+ * and branch to the address found there.
+ */
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system. The msm8x60
+ * does not support the ARM SCU, so just set the possible cpu mask to
+ * NR_CPUS.
+ */
+static void __init msm_smp_init_cpus(void)
+{
+ unsigned int i, ncores = get_core_count();
+
+ if (ncores > nr_cpu_ids) {
+ pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+ ncores, nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
+
+static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
+{
+}
+
+struct smp_operations msm_smp_ops __initdata = {
+ .smp_init_cpus = msm_smp_init_cpus,
+ .smp_prepare_cpus = msm_smp_prepare_cpus,
+ .smp_secondary_init = msm_secondary_init,
+ .smp_boot_secondary = msm_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = msm_cpu_die,
+#endif
+};
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH v2 0/5] Split mach-msm into legacy and mach-qcom (multiplatform)
From: Kumar Gala @ 2014-02-04 22:38 UTC (permalink / raw)
To: linux-arm-kernel
This is the splits the Qualcomm MSM platform into legacy support that we will
not try and convert to multiplatform and multiplatform support.
- k
Changes from v1:
* Added patch to remove hotplug.c
* Added patch to rename msm_ to qcom_
* Changes the Kconfig to drop CPU_V7
* used wfi() in cpu_die function
* Added git tree to MAINTAINERS file
Kumar Gala (5):
ARM: msm: kill off hotplug.c
clocksource: qcom: Move clocksource code out of mach-msm
arm: qcom: Split Qualcomm support into legacy and multiplatform
clocksource: qcom: split building of legacy vs multiplatform support
ARM: qcom: Rename various msm prefixed functions to qcom
arch/arm/mach-msm/board-dt.c | 41 ----
arch/arm/mach-msm/hotplug.c | 51 -----
arch/arm/mach-msm/platsmp.c | 130 --------------
arch/arm/mach-msm/scm-boot.c | 39 ----
arch/arm/mach-msm/scm-boot.h | 22 --
arch/arm/mach-msm/scm.c | 299 ---------------------------------
arch/arm/mach-msm/scm.h | 25 --
arch/arm/mach-msm/timer.c | 333 -------------------------------------
b/MAINTAINERS | 8
b/arch/arm/Kconfig | 7
b/arch/arm/Kconfig.debug | 2
b/arch/arm/Makefile | 1
b/arch/arm/boot/dts/Makefile | 6
b/arch/arm/mach-msm/Kconfig | 54 ------
b/arch/arm/mach-msm/Makefile | 8
b/arch/arm/mach-msm/common.h | 1
b/arch/arm/mach-qcom/Kconfig | 33 +++
b/arch/arm/mach-qcom/Makefile | 5
b/arch/arm/mach-qcom/board.c | 40 ++++
b/arch/arm/mach-qcom/scm-boot.c | 39 ++++
b/arch/arm/mach-qcom/scm-boot.h | 22 ++
b/arch/arm/mach-qcom/scm.c | 299 +++++++++++++++++++++++++++++++++
b/arch/arm/mach-qcom/scm.h | 25 ++
b/arch/arm/mach-qcom/smp.c | 137 +++++++++++++++
b/drivers/clocksource/Kconfig | 4
b/drivers/clocksource/Makefile | 1
b/drivers/clocksource/qcom-timer.c | 330 ++++++++++++++++++++++++++++++++++++
27 files changed, 957 insertions(+), 1005 deletions(-)
^ permalink raw reply
* [PATCH v2 1/5] ARM: msm: kill off hotplug.c
From: Kumar Gala @ 2014-02-04 22:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391553532-27001-1-git-send-email-galak@codeaurora.org>
Right now hotplug.c only really implements msm_cpu_die as a wfi. Just
move that implementation into platsmp.c. At the same time we use the
existing wfi() instead of inline asm.
Signed-off-by: Kumar Gala <galak@codeaurora.org>
---
arch/arm/mach-msm/Makefile | 1 -
arch/arm/mach-msm/common.h | 1 -
arch/arm/mach-msm/hotplug.c | 51 ---------------------------------------------
arch/arm/mach-msm/platsmp.c | 7 +++++++
4 files changed, 7 insertions(+), 53 deletions(-)
delete mode 100644 arch/arm/mach-msm/hotplug.c
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 721f27f..8327f60 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
-obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
diff --git a/arch/arm/mach-msm/common.h b/arch/arm/mach-msm/common.h
index 33c7725..0a4899b 100644
--- a/arch/arm/mach-msm/common.h
+++ b/arch/arm/mach-msm/common.h
@@ -24,7 +24,6 @@ extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
unsigned int mtype, void *caller);
extern struct smp_operations msm_smp_ops;
-extern void msm_cpu_die(unsigned int cpu);
struct msm_mmc_platform_data;
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
deleted file mode 100644
index cea80fc..0000000
--- a/arch/arm/mach-msm/hotplug.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2002 ARM Ltd.
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
-
-#include <asm/smp_plat.h>
-
-#include "common.h"
-
-static inline void cpu_enter_lowpower(void)
-{
-}
-
-static inline void cpu_leave_lowpower(void)
-{
-}
-
-static inline void platform_do_lowpower(unsigned int cpu)
-{
- asm("wfi"
- :
- :
- : "memory", "cc");
-}
-
-/*
- * platform-specific code to shutdown a CPU
- *
- * Called with IRQs disabled
- */
-void __ref msm_cpu_die(unsigned int cpu)
-{
- /*
- * we're ready for shutdown now, so do it
- */
- cpu_enter_lowpower();
- platform_do_lowpower(cpu);
-
- /*
- * bring this CPU back into the world of cache
- * coherency, and then restore interrupts
- */
- cpu_leave_lowpower();
-}
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 3721b31..251a91e 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -29,6 +29,13 @@ extern void secondary_startup(void);
static DEFINE_SPINLOCK(boot_lock);
+#ifdef CONFIG_HOTPLUG_CPU
+static void __ref msm_cpu_die(unsigned int cpu)
+{
+ wfi();
+}
+#endif
+
static inline int get_core_count(void)
{
/* 1 + the PART[1:0] field of MIDR */
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH v2 2/5] clocksource: qcom: Move clocksource code out of mach-msm
From: Kumar Gala @ 2014-02-04 22:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391553532-27001-1-git-send-email-galak@codeaurora.org>
We intent to share the clocksource code for MSM platforms between legacy
and multiplatform supported qcom SoCs.
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Kumar Gala <galak@codeaurora.org>
---
arch/arm/mach-msm/Kconfig | 13 +-
arch/arm/mach-msm/Makefile | 1 -
arch/arm/mach-msm/timer.c | 333 ---------------------------------------
drivers/clocksource/Kconfig | 4 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/qcom-timer.c | 329 ++++++++++++++++++++++++++++++++++++++
6 files changed, 339 insertions(+), 342 deletions(-)
delete mode 100644 arch/arm/mach-msm/timer.c
create mode 100644 drivers/clocksource/qcom-timer.c
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 9625cf3..3c4eca7 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -21,7 +21,7 @@ config ARCH_MSM8X60
select CPU_V7
select HAVE_SMP
select MSM_SCM if SMP
- select MSM_TIMER
+ select CLKSRC_QCOM
config ARCH_MSM8960
bool "Enable support for MSM8960"
@@ -29,7 +29,7 @@ config ARCH_MSM8960
select CPU_V7
select HAVE_SMP
select MSM_SCM if SMP
- select MSM_TIMER
+ select CLKSRC_QCOM
config ARCH_MSM8974
bool "Enable support for MSM8974"
@@ -54,7 +54,7 @@ config ARCH_MSM7X00A
select MACH_TROUT if !MACH_HALIBUT
select MSM_PROC_COMM
select MSM_SMD
- select MSM_TIMER
+ select CLKSRC_QCOM
select MSM_SMD_PKG3
config ARCH_MSM7X30
@@ -66,7 +66,7 @@ config ARCH_MSM7X30
select MSM_GPIOMUX
select MSM_PROC_COMM
select MSM_SMD
- select MSM_TIMER
+ select CLKSRC_QCOM
select MSM_VIC
config ARCH_QSD8X50
@@ -78,7 +78,7 @@ config ARCH_QSD8X50
select MSM_GPIOMUX
select MSM_PROC_COMM
select MSM_SMD
- select MSM_TIMER
+ select CLKSRC_QCOM
select MSM_VIC
endchoice
@@ -153,7 +153,4 @@ config MSM_GPIOMUX
config MSM_SCM
bool
-config MSM_TIMER
- bool
-
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 8327f60..04b1bee 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,4 +1,3 @@
-obj-$(CONFIG_MSM_TIMER) += timer.o
obj-$(CONFIG_MSM_PROC_COMM) += clock.o
obj-$(CONFIG_MSM_VIC) += irq-vic.o
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
deleted file mode 100644
index fd16449..0000000
--- a/arch/arm/mach-msm/timer.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- *
- * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/cpu.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/sched_clock.h>
-
-#include <asm/mach/time.h>
-
-#include "common.h"
-
-#define TIMER_MATCH_VAL 0x0000
-#define TIMER_COUNT_VAL 0x0004
-#define TIMER_ENABLE 0x0008
-#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1)
-#define TIMER_ENABLE_EN BIT(0)
-#define TIMER_CLEAR 0x000C
-#define DGT_CLK_CTL 0x10
-#define DGT_CLK_CTL_DIV_4 0x3
-#define TIMER_STS_GPT0_CLR_PEND BIT(10)
-
-#define GPT_HZ 32768
-
-#define MSM_DGT_SHIFT 5
-
-static void __iomem *event_base;
-static void __iomem *sts_base;
-
-static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
-{
- struct clock_event_device *evt = dev_id;
- /* Stop the timer tick */
- if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
- u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
- ctrl &= ~TIMER_ENABLE_EN;
- writel_relaxed(ctrl, event_base + TIMER_ENABLE);
- }
- evt->event_handler(evt);
- return IRQ_HANDLED;
-}
-
-static int msm_timer_set_next_event(unsigned long cycles,
- struct clock_event_device *evt)
-{
- u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-
- ctrl &= ~TIMER_ENABLE_EN;
- writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-
- writel_relaxed(ctrl, event_base + TIMER_CLEAR);
- writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
-
- if (sts_base)
- while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
- cpu_relax();
-
- writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
- return 0;
-}
-
-static void msm_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- u32 ctrl;
-
- ctrl = readl_relaxed(event_base + TIMER_ENABLE);
- ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
-
- switch (mode) {
- case CLOCK_EVT_MODE_RESUME:
- case CLOCK_EVT_MODE_PERIODIC:
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- /* Timer is enabled in set_next_event */
- break;
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- break;
- }
- writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-}
-
-static struct clock_event_device __percpu *msm_evt;
-
-static void __iomem *source_base;
-
-static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
-{
- return readl_relaxed(source_base + TIMER_COUNT_VAL);
-}
-
-static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
-{
- /*
- * Shift timer count down by a constant due to unreliable lower bits
- * on some targets.
- */
- return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
-}
-
-static struct clocksource msm_clocksource = {
- .name = "dg_timer",
- .rating = 300,
- .read = msm_read_timer_count,
- .mask = CLOCKSOURCE_MASK(32),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static int msm_timer_irq;
-static int msm_timer_has_ppi;
-
-static int msm_local_timer_setup(struct clock_event_device *evt)
-{
- int cpu = smp_processor_id();
- int err;
-
- evt->irq = msm_timer_irq;
- evt->name = "msm_timer";
- evt->features = CLOCK_EVT_FEAT_ONESHOT;
- evt->rating = 200;
- evt->set_mode = msm_timer_set_mode;
- evt->set_next_event = msm_timer_set_next_event;
- evt->cpumask = cpumask_of(cpu);
-
- clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
-
- if (msm_timer_has_ppi) {
- enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
- } else {
- err = request_irq(evt->irq, msm_timer_interrupt,
- IRQF_TIMER | IRQF_NOBALANCING |
- IRQF_TRIGGER_RISING, "gp_timer", evt);
- if (err)
- pr_err("request_irq failed\n");
- }
-
- return 0;
-}
-
-static void msm_local_timer_stop(struct clock_event_device *evt)
-{
- evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
- disable_percpu_irq(evt->irq);
-}
-
-static int msm_timer_cpu_notify(struct notifier_block *self,
- unsigned long action, void *hcpu)
-{
- /*
- * Grab cpu pointer in each case to avoid spurious
- * preemptible warnings
- */
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_STARTING:
- msm_local_timer_setup(this_cpu_ptr(msm_evt));
- break;
- case CPU_DYING:
- msm_local_timer_stop(this_cpu_ptr(msm_evt));
- break;
- }
-
- return NOTIFY_OK;
-}
-
-static struct notifier_block msm_timer_cpu_nb = {
- .notifier_call = msm_timer_cpu_notify,
-};
-
-static u64 notrace msm_sched_clock_read(void)
-{
- return msm_clocksource.read(&msm_clocksource);
-}
-
-static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
- bool percpu)
-{
- struct clocksource *cs = &msm_clocksource;
- int res = 0;
-
- msm_timer_irq = irq;
- msm_timer_has_ppi = percpu;
-
- msm_evt = alloc_percpu(struct clock_event_device);
- if (!msm_evt) {
- pr_err("memory allocation failed for clockevents\n");
- goto err;
- }
-
- if (percpu)
- res = request_percpu_irq(irq, msm_timer_interrupt,
- "gp_timer", msm_evt);
-
- if (res) {
- pr_err("request_percpu_irq failed\n");
- } else {
- res = register_cpu_notifier(&msm_timer_cpu_nb);
- if (res) {
- free_percpu_irq(irq, msm_evt);
- goto err;
- }
-
- /* Immediately configure the timer on the boot CPU */
- msm_local_timer_setup(__this_cpu_ptr(msm_evt));
- }
-
-err:
- writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
- res = clocksource_register_hz(cs, dgt_hz);
- if (res)
- pr_err("clocksource_register failed\n");
- sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
-}
-
-#ifdef CONFIG_OF
-static void __init msm_dt_timer_init(struct device_node *np)
-{
- u32 freq;
- int irq;
- struct resource res;
- u32 percpu_offset;
- void __iomem *base;
- void __iomem *cpu0_base;
-
- base = of_iomap(np, 0);
- if (!base) {
- pr_err("Failed to map event base\n");
- return;
- }
-
- /* We use GPT0 for the clockevent */
- irq = irq_of_parse_and_map(np, 1);
- if (irq <= 0) {
- pr_err("Can't get irq\n");
- return;
- }
-
- /* We use CPU0's DGT for the clocksource */
- if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
- percpu_offset = 0;
-
- if (of_address_to_resource(np, 0, &res)) {
- pr_err("Failed to parse DGT resource\n");
- return;
- }
-
- cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
- if (!cpu0_base) {
- pr_err("Failed to map source base\n");
- return;
- }
-
- if (of_property_read_u32(np, "clock-frequency", &freq)) {
- pr_err("Unknown frequency\n");
- return;
- }
-
- event_base = base + 0x4;
- sts_base = base + 0x88;
- source_base = cpu0_base + 0x24;
- freq /= 4;
- writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
-
- msm_timer_init(freq, 32, irq, !!percpu_offset);
-}
-CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
-CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
-#endif
-
-static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
- u32 sts)
-{
- void __iomem *base;
-
- base = ioremap(addr, SZ_256);
- if (!base) {
- pr_err("Failed to map timer base\n");
- return -ENOMEM;
- }
- event_base = base + event;
- source_base = base + source;
- if (sts)
- sts_base = base + sts;
-
- return 0;
-}
-
-void __init msm7x01_timer_init(void)
-{
- struct clocksource *cs = &msm_clocksource;
-
- if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
- return;
- cs->read = msm_read_timer_count_shift;
- cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
- /* 600 KHz */
- msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
- false);
-}
-
-void __init msm7x30_timer_init(void)
-{
- if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
- return;
- msm_timer_init(24576000 / 4, 32, 1, false);
-}
-
-void __init qsd8x50_timer_init(void)
-{
- if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
- return;
- msm_timer_init(19200000 / 4, 32, 7, false);
-}
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cd6950f..81caa16 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -140,3 +140,7 @@ config VF_PIT_TIMER
bool
help
Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
+
+config CLKSRC_QCOM
+ bool
+ depends on ARCH_MSM
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index c7ca50a..2e0c0cc 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
+obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c
new file mode 100644
index 0000000..dca829e
--- /dev/null
+++ b/drivers/clocksource/qcom-timer.c
@@ -0,0 +1,329 @@
+/*
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009-2012,2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+#define TIMER_MATCH_VAL 0x0000
+#define TIMER_COUNT_VAL 0x0004
+#define TIMER_ENABLE 0x0008
+#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1)
+#define TIMER_ENABLE_EN BIT(0)
+#define TIMER_CLEAR 0x000C
+#define DGT_CLK_CTL 0x10
+#define DGT_CLK_CTL_DIV_4 0x3
+#define TIMER_STS_GPT0_CLR_PEND BIT(10)
+
+#define GPT_HZ 32768
+
+#define MSM_DGT_SHIFT 5
+
+static void __iomem *event_base;
+static void __iomem *sts_base;
+
+static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+ /* Stop the timer tick */
+ if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
+ u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
+ ctrl &= ~TIMER_ENABLE_EN;
+ writel_relaxed(ctrl, event_base + TIMER_ENABLE);
+ }
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static int msm_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
+
+ ctrl &= ~TIMER_ENABLE_EN;
+ writel_relaxed(ctrl, event_base + TIMER_ENABLE);
+
+ writel_relaxed(ctrl, event_base + TIMER_CLEAR);
+ writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
+
+ if (sts_base)
+ while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
+ cpu_relax();
+
+ writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
+ return 0;
+}
+
+static void msm_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 ctrl;
+
+ ctrl = readl_relaxed(event_base + TIMER_ENABLE);
+ ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_RESUME:
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Timer is enabled in set_next_event */
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+ }
+ writel_relaxed(ctrl, event_base + TIMER_ENABLE);
+}
+
+static struct clock_event_device __percpu *msm_evt;
+
+static void __iomem *source_base;
+
+static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
+{
+ return readl_relaxed(source_base + TIMER_COUNT_VAL);
+}
+
+static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
+{
+ /*
+ * Shift timer count down by a constant due to unreliable lower bits
+ * on some targets.
+ */
+ return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
+}
+
+static struct clocksource msm_clocksource = {
+ .name = "dg_timer",
+ .rating = 300,
+ .read = msm_read_timer_count,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int msm_timer_irq;
+static int msm_timer_has_ppi;
+
+static int msm_local_timer_setup(struct clock_event_device *evt)
+{
+ int cpu = smp_processor_id();
+ int err;
+
+ evt->irq = msm_timer_irq;
+ evt->name = "msm_timer";
+ evt->features = CLOCK_EVT_FEAT_ONESHOT;
+ evt->rating = 200;
+ evt->set_mode = msm_timer_set_mode;
+ evt->set_next_event = msm_timer_set_next_event;
+ evt->cpumask = cpumask_of(cpu);
+
+ clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
+
+ if (msm_timer_has_ppi) {
+ enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
+ } else {
+ err = request_irq(evt->irq, msm_timer_interrupt,
+ IRQF_TIMER | IRQF_NOBALANCING |
+ IRQF_TRIGGER_RISING, "gp_timer", evt);
+ if (err)
+ pr_err("request_irq failed\n");
+ }
+
+ return 0;
+}
+
+static void msm_local_timer_stop(struct clock_event_device *evt)
+{
+ evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+ disable_percpu_irq(evt->irq);
+}
+
+static int msm_timer_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ /*
+ * Grab cpu pointer in each case to avoid spurious
+ * preemptible warnings
+ */
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_STARTING:
+ msm_local_timer_setup(this_cpu_ptr(msm_evt));
+ break;
+ case CPU_DYING:
+ msm_local_timer_stop(this_cpu_ptr(msm_evt));
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block msm_timer_cpu_nb = {
+ .notifier_call = msm_timer_cpu_notify,
+};
+
+static u64 notrace msm_sched_clock_read(void)
+{
+ return msm_clocksource.read(&msm_clocksource);
+}
+
+static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
+ bool percpu)
+{
+ struct clocksource *cs = &msm_clocksource;
+ int res = 0;
+
+ msm_timer_irq = irq;
+ msm_timer_has_ppi = percpu;
+
+ msm_evt = alloc_percpu(struct clock_event_device);
+ if (!msm_evt) {
+ pr_err("memory allocation failed for clockevents\n");
+ goto err;
+ }
+
+ if (percpu)
+ res = request_percpu_irq(irq, msm_timer_interrupt,
+ "gp_timer", msm_evt);
+
+ if (res) {
+ pr_err("request_percpu_irq failed\n");
+ } else {
+ res = register_cpu_notifier(&msm_timer_cpu_nb);
+ if (res) {
+ free_percpu_irq(irq, msm_evt);
+ goto err;
+ }
+
+ /* Immediately configure the timer on the boot CPU */
+ msm_local_timer_setup(__this_cpu_ptr(msm_evt));
+ }
+
+err:
+ writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
+ res = clocksource_register_hz(cs, dgt_hz);
+ if (res)
+ pr_err("clocksource_register failed\n");
+ sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
+}
+
+#ifdef CONFIG_OF
+static void __init msm_dt_timer_init(struct device_node *np)
+{
+ u32 freq;
+ int irq;
+ struct resource res;
+ u32 percpu_offset;
+ void __iomem *base;
+ void __iomem *cpu0_base;
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_err("Failed to map event base\n");
+ return;
+ }
+
+ /* We use GPT0 for the clockevent */
+ irq = irq_of_parse_and_map(np, 1);
+ if (irq <= 0) {
+ pr_err("Can't get irq\n");
+ return;
+ }
+
+ /* We use CPU0's DGT for the clocksource */
+ if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
+ percpu_offset = 0;
+
+ if (of_address_to_resource(np, 0, &res)) {
+ pr_err("Failed to parse DGT resource\n");
+ return;
+ }
+
+ cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
+ if (!cpu0_base) {
+ pr_err("Failed to map source base\n");
+ return;
+ }
+
+ if (of_property_read_u32(np, "clock-frequency", &freq)) {
+ pr_err("Unknown frequency\n");
+ return;
+ }
+
+ event_base = base + 0x4;
+ sts_base = base + 0x88;
+ source_base = cpu0_base + 0x24;
+ freq /= 4;
+ writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
+
+ msm_timer_init(freq, 32, irq, !!percpu_offset);
+}
+CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
+CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
+#endif
+
+static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
+ u32 sts)
+{
+ void __iomem *base;
+
+ base = ioremap(addr, SZ_256);
+ if (!base) {
+ pr_err("Failed to map timer base\n");
+ return -ENOMEM;
+ }
+ event_base = base + event;
+ source_base = base + source;
+ if (sts)
+ sts_base = base + sts;
+
+ return 0;
+}
+
+void __init msm7x01_timer_init(void)
+{
+ struct clocksource *cs = &msm_clocksource;
+
+ if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
+ return;
+ cs->read = msm_read_timer_count_shift;
+ cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
+ /* 600 KHz */
+ msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
+ false);
+}
+
+void __init msm7x30_timer_init(void)
+{
+ if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
+ return;
+ msm_timer_init(24576000 / 4, 32, 1, false);
+}
+
+void __init qsd8x50_timer_init(void)
+{
+ if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
+ return;
+ msm_timer_init(19200000 / 4, 32, 7, false);
+}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH v2 3/5] arm: qcom: Split Qualcomm support into legacy and multiplatform
From: Kumar Gala @ 2014-02-04 22:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391553532-27001-1-git-send-email-galak@codeaurora.org>
Introduce a new mach-qcom that will support SoCs that intend to be
multiplatform compatiable while keeping mach-msm to legacy SoC/board
support that will not transition over to multiplatform.
As part of this, we move support for MSM8X60, MSM8960 and MSM8974 over
to mach-qcom.
Signed-off-by: Kumar Gala <galak@codeaurora.org>
---
MAINTAINERS | 8 ++
arch/arm/Kconfig | 7 +-
arch/arm/Kconfig.debug | 2 +-
arch/arm/Makefile | 1 +
arch/arm/boot/dts/Makefile | 6 +-
arch/arm/mach-msm/Kconfig | 45 +------
arch/arm/mach-msm/Makefile | 6 -
arch/arm/mach-msm/board-dt.c | 41 ------
arch/arm/mach-msm/platsmp.c | 137 -------------------
arch/arm/mach-msm/scm-boot.c | 39 ------
arch/arm/mach-msm/scm-boot.h | 22 ----
arch/arm/mach-msm/scm.c | 299 ------------------------------------------
arch/arm/mach-msm/scm.h | 25 ----
arch/arm/mach-qcom/Kconfig | 33 +++++
arch/arm/mach-qcom/Makefile | 5 +
arch/arm/mach-qcom/board.c | 40 ++++++
arch/arm/mach-qcom/scm-boot.c | 39 ++++++
arch/arm/mach-qcom/scm-boot.h | 22 ++++
arch/arm/mach-qcom/scm.c | 299 ++++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-qcom/scm.h | 25 ++++
arch/arm/mach-qcom/smp.c | 137 +++++++++++++++++++
21 files changed, 619 insertions(+), 619 deletions(-)
delete mode 100644 arch/arm/mach-msm/board-dt.c
delete mode 100644 arch/arm/mach-msm/platsmp.c
delete mode 100644 arch/arm/mach-msm/scm-boot.c
delete mode 100644 arch/arm/mach-msm/scm-boot.h
delete mode 100644 arch/arm/mach-msm/scm.c
delete mode 100644 arch/arm/mach-msm/scm.h
create mode 100644 arch/arm/mach-qcom/Kconfig
create mode 100644 arch/arm/mach-qcom/Makefile
create mode 100644 arch/arm/mach-qcom/board.c
create mode 100644 arch/arm/mach-qcom/scm-boot.c
create mode 100644 arch/arm/mach-qcom/scm-boot.h
create mode 100644 arch/arm/mach-qcom/scm.c
create mode 100644 arch/arm/mach-qcom/scm.h
create mode 100644 arch/arm/mach-qcom/smp.c
diff --git a/MAINTAINERS b/MAINTAINERS
index b2cf5cf..402be60 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1167,6 +1167,14 @@ L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
W: http://www.arm.linux.org.uk/
S: Maintained
+ARM/QUALCOMM SUPPORT
+M: Kumar Gala <galak@codeaurora.org>
+M: David Brown <davidb@codeaurora.org>
+L: linux-arm-msm at vger.kernel.org
+S: Maintained
+F: arch/arm/mach-qcom/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
+
ARM/RADISYS ENP2611 MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e254198..f093f20 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -657,9 +657,8 @@ config ARCH_PXA
help
Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
-config ARCH_MSM_NODT
- bool "Qualcomm MSM"
- select ARCH_MSM
+config ARCH_MSM
+ bool "Qualcomm MSM (non-multiplatform)"
select ARCH_REQUIRE_GPIOLIB
select COMMON_CLK
select GENERIC_CLOCKEVENTS
@@ -1005,6 +1004,8 @@ source "arch/arm/plat-pxa/Kconfig"
source "arch/arm/mach-mmp/Kconfig"
+source "arch/arm/mach-qcom/Kconfig"
+
source "arch/arm/mach-realview/Kconfig"
source "arch/arm/mach-rockchip/Kconfig"
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 0531da8..4491c7b 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -956,7 +956,7 @@ config DEBUG_STI_UART
config DEBUG_MSM_UART
bool
- depends on ARCH_MSM
+ depends on ARCH_MSM || ARCH_QCOM
config DEBUG_LL_INCLUDE
string
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 08a9ef5..51e5bed 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -180,6 +180,7 @@ machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2
machine-$(CONFIG_ARCH_ORION5X) += orion5x
machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell
machine-$(CONFIG_ARCH_PXA) += pxa
+machine-$(CONFIG_ARCH_QCOM) += qcom
machine-$(CONFIG_ARCH_REALVIEW) += realview
machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip
machine-$(CONFIG_ARCH_RPC) += rpc
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b9d6a8b..c9eaf1f 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -118,9 +118,6 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
kirkwood-ts219-6282.dtb
dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
-dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \
- qcom-msm8960-cdp.dtb \
- qcom-apq8074-dragonboard.dtb
dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
armada-370-mirabox.dtb \
armada-370-netgear-rn102.dtb \
@@ -232,6 +229,9 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
dra7-evm.dtb
dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
+ qcom-msm8960-cdp.dtb \
+ qcom-apq8074-dragonboard.dtb
dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
ste-hrefprev60-stuib.dtb \
ste-hrefprev60-tvk.dtb \
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 3c4eca7..a7f959e 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1,50 +1,9 @@
-config ARCH_MSM
- bool
-
-config ARCH_MSM_DT
- bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7
- select ARCH_MSM
- select ARCH_REQUIRE_GPIOLIB
- select CLKSRC_OF
- select GENERIC_CLOCKEVENTS
- help
- Support for Qualcomm's devicetree based MSM systems.
-
if ARCH_MSM
-menu "Qualcomm MSM SoC Selection"
- depends on ARCH_MSM_DT
-
-config ARCH_MSM8X60
- bool "Enable support for MSM8X60"
- select ARM_GIC
- select CPU_V7
- select HAVE_SMP
- select MSM_SCM if SMP
- select CLKSRC_QCOM
-
-config ARCH_MSM8960
- bool "Enable support for MSM8960"
- select ARM_GIC
- select CPU_V7
- select HAVE_SMP
- select MSM_SCM if SMP
- select CLKSRC_QCOM
-
-config ARCH_MSM8974
- bool "Enable support for MSM8974"
- select ARM_GIC
- select CPU_V7
- select HAVE_ARM_ARCH_TIMER
- select HAVE_SMP
- select MSM_SCM if SMP
-
-endmenu
-
choice
prompt "Qualcomm MSM SoC Type"
default ARCH_MSM7X00A
- depends on ARCH_MSM_NODT
+ depends on ARCH_MSM
config ARCH_MSM7X00A
bool "MSM7x00A / MSM7x01A"
@@ -99,7 +58,7 @@ config MSM_VIC
bool
menu "Qualcomm MSM Board Type"
- depends on ARCH_MSM_NODT
+ depends on ARCH_MSM
config MACH_HALIBUT
depends on ARCH_MSM
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 04b1bee..27c078a 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -13,17 +13,11 @@ obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o
obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
obj-$(CONFIG_MSM_SMD) += last_radio_log.o
-obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
-
-CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
-
-obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
-obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o
obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
deleted file mode 100644
index 1f11d93..0000000
--- a/arch/arm/mach-msm/board-dt.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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.
- */
-
-#include <linux/init.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-
-static const char * const msm_dt_match[] __initconst = {
- "qcom,msm8660-fluid",
- "qcom,msm8660-surf",
- "qcom,msm8960-cdp",
- NULL
-};
-
-static const char * const apq8074_dt_match[] __initconst = {
- "qcom,apq8074-dragonboard",
- NULL
-};
-
-DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
- .smp = smp_ops(msm_smp_ops),
- .dt_compat = msm_dt_match,
-MACHINE_END
-
-DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)")
- .dt_compat = apq8074_dt_match,
-MACHINE_END
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
deleted file mode 100644
index 251a91e..0000000
--- a/arch/arm/mach-msm/platsmp.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2002 ARM Ltd.
- * All Rights Reserved
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-
-#include <asm/cputype.h>
-#include <asm/smp_plat.h>
-
-#include "scm-boot.h"
-#include "common.h"
-
-#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
-#define SCSS_CPU1CORE_RESET 0xD80
-#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
-
-extern void secondary_startup(void);
-
-static DEFINE_SPINLOCK(boot_lock);
-
-#ifdef CONFIG_HOTPLUG_CPU
-static void __ref msm_cpu_die(unsigned int cpu)
-{
- wfi();
-}
-#endif
-
-static inline int get_core_count(void)
-{
- /* 1 + the PART[1:0] field of MIDR */
- return ((read_cpuid_id() >> 4) & 3) + 1;
-}
-
-static void msm_secondary_init(unsigned int cpu)
-{
- /*
- * Synchronise with the boot thread.
- */
- spin_lock(&boot_lock);
- spin_unlock(&boot_lock);
-}
-
-static void prepare_cold_cpu(unsigned int cpu)
-{
- int ret;
- ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
- SCM_FLAG_COLDBOOT_CPU1);
- if (ret == 0) {
- void __iomem *sc1_base_ptr;
- sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
- if (sc1_base_ptr) {
- writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
- writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
- writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
- iounmap(sc1_base_ptr);
- }
- } else
- printk(KERN_DEBUG "Failed to set secondary core boot "
- "address\n");
-}
-
-static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
- static int cold_boot_done;
-
- /* Only need to bring cpu out of reset this way once */
- if (cold_boot_done == false) {
- prepare_cold_cpu(cpu);
- cold_boot_done = true;
- }
-
- /*
- * set synchronisation state between this boot processor
- * and the secondary one
- */
- spin_lock(&boot_lock);
-
- /*
- * Send the secondary CPU a soft interrupt, thereby causing
- * the boot monitor to read the system wide flags register,
- * and branch to the address found there.
- */
- arch_send_wakeup_ipi_mask(cpumask_of(cpu));
-
- /*
- * now the secondary core is starting up let it run its
- * calibrations, then wait for it to finish
- */
- spin_unlock(&boot_lock);
-
- return 0;
-}
-
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system. The msm8x60
- * does not support the ARM SCU, so just set the possible cpu mask to
- * NR_CPUS.
- */
-static void __init msm_smp_init_cpus(void)
-{
- unsigned int i, ncores = get_core_count();
-
- if (ncores > nr_cpu_ids) {
- pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
- ncores, nr_cpu_ids);
- ncores = nr_cpu_ids;
- }
-
- for (i = 0; i < ncores; i++)
- set_cpu_possible(i, true);
-}
-
-static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
-{
-}
-
-struct smp_operations msm_smp_ops __initdata = {
- .smp_init_cpus = msm_smp_init_cpus,
- .smp_prepare_cpus = msm_smp_prepare_cpus,
- .smp_secondary_init = msm_secondary_init,
- .smp_boot_secondary = msm_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
- .cpu_die = msm_cpu_die,
-#endif
-};
diff --git a/arch/arm/mach-msm/scm-boot.c b/arch/arm/mach-msm/scm-boot.c
deleted file mode 100644
index 45cee3e..0000000
--- a/arch/arm/mach-msm/scm-boot.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "scm.h"
-#include "scm-boot.h"
-
-/*
- * Set the cold/warm boot address for one of the CPU cores.
- */
-int scm_set_boot_addr(phys_addr_t addr, int flags)
-{
- struct {
- unsigned int flags;
- phys_addr_t addr;
- } cmd;
-
- cmd.addr = addr;
- cmd.flags = flags;
- return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
- &cmd, sizeof(cmd), NULL, 0);
-}
-EXPORT_SYMBOL(scm_set_boot_addr);
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
deleted file mode 100644
index 7be32ff..0000000
--- a/arch/arm/mach-msm/scm-boot.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef __MACH_SCM_BOOT_H
-#define __MACH_SCM_BOOT_H
-
-#define SCM_BOOT_ADDR 0x1
-#define SCM_FLAG_COLDBOOT_CPU1 0x1
-#define SCM_FLAG_WARMBOOT_CPU1 0x2
-#define SCM_FLAG_WARMBOOT_CPU0 0x4
-
-int scm_set_boot_addr(phys_addr_t addr, int flags);
-
-#endif
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
deleted file mode 100644
index c536fd6..0000000
--- a/arch/arm/mach-msm/scm.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-
-#include <asm/cacheflush.h>
-
-#include "scm.h"
-
-/* Cache line size for msm8x60 */
-#define CACHELINESIZE 32
-
-#define SCM_ENOMEM -5
-#define SCM_EOPNOTSUPP -4
-#define SCM_EINVAL_ADDR -3
-#define SCM_EINVAL_ARG -2
-#define SCM_ERROR -1
-#define SCM_INTERRUPTED 1
-
-static DEFINE_MUTEX(scm_lock);
-
-/**
- * struct scm_command - one SCM command buffer
- * @len: total available memory for command and response
- * @buf_offset: start of command buffer
- * @resp_hdr_offset: start of response buffer
- * @id: command to be executed
- * @buf: buffer returned from scm_get_command_buffer()
- *
- * An SCM command is laid out in memory as follows:
- *
- * ------------------- <--- struct scm_command
- * | command header |
- * ------------------- <--- scm_get_command_buffer()
- * | command buffer |
- * ------------------- <--- struct scm_response and
- * | response header | scm_command_to_response()
- * ------------------- <--- scm_get_response_buffer()
- * | response buffer |
- * -------------------
- *
- * There can be arbitrary padding between the headers and buffers so
- * you should always use the appropriate scm_get_*_buffer() routines
- * to access the buffers in a safe manner.
- */
-struct scm_command {
- u32 len;
- u32 buf_offset;
- u32 resp_hdr_offset;
- u32 id;
- u32 buf[0];
-};
-
-/**
- * struct scm_response - one SCM response buffer
- * @len: total available memory for response
- * @buf_offset: start of response data relative to start of scm_response
- * @is_complete: indicates if the command has finished processing
- */
-struct scm_response {
- u32 len;
- u32 buf_offset;
- u32 is_complete;
-};
-
-/**
- * alloc_scm_command() - Allocate an SCM command
- * @cmd_size: size of the command buffer
- * @resp_size: size of the response buffer
- *
- * Allocate an SCM command, including enough room for the command
- * and response headers as well as the command and response buffers.
- *
- * Returns a valid &scm_command on success or %NULL if the allocation fails.
- */
-static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
-{
- struct scm_command *cmd;
- size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
- resp_size;
-
- cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
- if (cmd) {
- cmd->len = len;
- cmd->buf_offset = offsetof(struct scm_command, buf);
- cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
- }
- return cmd;
-}
-
-/**
- * free_scm_command() - Free an SCM command
- * @cmd: command to free
- *
- * Free an SCM command.
- */
-static inline void free_scm_command(struct scm_command *cmd)
-{
- kfree(cmd);
-}
-
-/**
- * scm_command_to_response() - Get a pointer to a scm_response
- * @cmd: command
- *
- * Returns a pointer to a response for a command.
- */
-static inline struct scm_response *scm_command_to_response(
- const struct scm_command *cmd)
-{
- return (void *)cmd + cmd->resp_hdr_offset;
-}
-
-/**
- * scm_get_command_buffer() - Get a pointer to a command buffer
- * @cmd: command
- *
- * Returns a pointer to the command buffer of a command.
- */
-static inline void *scm_get_command_buffer(const struct scm_command *cmd)
-{
- return (void *)cmd->buf;
-}
-
-/**
- * scm_get_response_buffer() - Get a pointer to a response buffer
- * @rsp: response
- *
- * Returns a pointer to a response buffer of a response.
- */
-static inline void *scm_get_response_buffer(const struct scm_response *rsp)
-{
- return (void *)rsp + rsp->buf_offset;
-}
-
-static int scm_remap_error(int err)
-{
- switch (err) {
- case SCM_ERROR:
- return -EIO;
- case SCM_EINVAL_ADDR:
- case SCM_EINVAL_ARG:
- return -EINVAL;
- case SCM_EOPNOTSUPP:
- return -EOPNOTSUPP;
- case SCM_ENOMEM:
- return -ENOMEM;
- }
- return -EINVAL;
-}
-
-static u32 smc(u32 cmd_addr)
-{
- int context_id;
- register u32 r0 asm("r0") = 1;
- register u32 r1 asm("r1") = (u32)&context_id;
- register u32 r2 asm("r2") = cmd_addr;
- do {
- asm volatile(
- __asmeq("%0", "r0")
- __asmeq("%1", "r0")
- __asmeq("%2", "r1")
- __asmeq("%3", "r2")
-#ifdef REQUIRES_SEC
- ".arch_extension sec\n"
-#endif
- "smc #0 @ switch to secure world\n"
- : "=r" (r0)
- : "r" (r0), "r" (r1), "r" (r2)
- : "r3");
- } while (r0 == SCM_INTERRUPTED);
-
- return r0;
-}
-
-static int __scm_call(const struct scm_command *cmd)
-{
- int ret;
- u32 cmd_addr = virt_to_phys(cmd);
-
- /*
- * Flush the entire cache here so callers don't have to remember
- * to flush the cache when passing physical addresses to the secure
- * side in the buffer.
- */
- flush_cache_all();
- ret = smc(cmd_addr);
- if (ret < 0)
- ret = scm_remap_error(ret);
-
- return ret;
-}
-
-/**
- * scm_call() - Send an SCM command
- * @svc_id: service identifier
- * @cmd_id: command identifier
- * @cmd_buf: command buffer
- * @cmd_len: length of the command buffer
- * @resp_buf: response buffer
- * @resp_len: length of the response buffer
- *
- * Sends a command to the SCM and waits for the command to finish processing.
- */
-int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
- void *resp_buf, size_t resp_len)
-{
- int ret;
- struct scm_command *cmd;
- struct scm_response *rsp;
-
- cmd = alloc_scm_command(cmd_len, resp_len);
- if (!cmd)
- return -ENOMEM;
-
- cmd->id = (svc_id << 10) | cmd_id;
- if (cmd_buf)
- memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
-
- mutex_lock(&scm_lock);
- ret = __scm_call(cmd);
- mutex_unlock(&scm_lock);
- if (ret)
- goto out;
-
- rsp = scm_command_to_response(cmd);
- do {
- u32 start = (u32)rsp;
- u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
- start &= ~(CACHELINESIZE - 1);
- while (start < end) {
- asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
- : "memory");
- start += CACHELINESIZE;
- }
- } while (!rsp->is_complete);
-
- if (resp_buf)
- memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
-out:
- free_scm_command(cmd);
- return ret;
-}
-EXPORT_SYMBOL(scm_call);
-
-u32 scm_get_version(void)
-{
- int context_id;
- static u32 version = -1;
- register u32 r0 asm("r0");
- register u32 r1 asm("r1");
-
- if (version != -1)
- return version;
-
- mutex_lock(&scm_lock);
-
- r0 = 0x1 << 8;
- r1 = (u32)&context_id;
- do {
- asm volatile(
- __asmeq("%0", "r0")
- __asmeq("%1", "r1")
- __asmeq("%2", "r0")
- __asmeq("%3", "r1")
-#ifdef REQUIRES_SEC
- ".arch_extension sec\n"
-#endif
- "smc #0 @ switch to secure world\n"
- : "=r" (r0), "=r" (r1)
- : "r" (r0), "r" (r1)
- : "r2", "r3");
- } while (r0 == SCM_INTERRUPTED);
-
- version = r1;
- mutex_unlock(&scm_lock);
-
- return version;
-}
-EXPORT_SYMBOL(scm_get_version);
diff --git a/arch/arm/mach-msm/scm.h b/arch/arm/mach-msm/scm.h
deleted file mode 100644
index 00b31ea..0000000
--- a/arch/arm/mach-msm/scm.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef __MACH_SCM_H
-#define __MACH_SCM_H
-
-#define SCM_SVC_BOOT 0x1
-#define SCM_SVC_PIL 0x2
-
-extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
- void *resp_buf, size_t resp_len);
-
-#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
-
-extern u32 scm_get_version(void);
-
-#endif
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
new file mode 100644
index 0000000..755b0db
--- /dev/null
+++ b/arch/arm/mach-qcom/Kconfig
@@ -0,0 +1,33 @@
+config ARCH_QCOM
+ bool "Qualcomm Support" if ARCH_MULTI_V7
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKSRC_OF
+ select GENERIC_CLOCKEVENTS
+ select ARM_GIC
+ select HAVE_SMP
+ select QCOM_SCM if SMP
+ help
+ Support for Qualcomm's devicetree based systems.
+
+if ARCH_QCOM
+
+menu "Qualcomm SoC Selection"
+
+config ARCH_MSM8X60
+ bool "Enable support for MSM8X60"
+ select CLKSRC_QCOM
+
+config ARCH_MSM8960
+ bool "Enable support for MSM8960"
+ select CLKSRC_QCOM
+
+config ARCH_MSM8974
+ bool "Enable support for MSM8974"
+ select HAVE_ARM_ARCH_TIMER
+
+endmenu
+
+config QCOM_SCM
+ bool
+
+endif
diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
new file mode 100644
index 0000000..c0ba0ef
--- /dev/null
+++ b/arch/arm/mach-qcom/Makefile
@@ -0,0 +1,5 @@
+obj-y := board.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
+
+CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
new file mode 100644
index 0000000..4529f6b
--- /dev/null
+++ b/arch/arm/mach-qcom/board.c
@@ -0,0 +1,40 @@
+/* Copyright (c) 2010-2014 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+extern struct smp_operations msm_smp_ops;
+
+static const char * const qcom_dt_match[] __initconst = {
+ "qcom,msm8660-surf",
+ "qcom,msm8960-cdp",
+ NULL
+};
+
+static const char * const apq8074_dt_match[] __initconst = {
+ "qcom,apq8074-dragonboard",
+ NULL
+};
+
+DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
+ .smp = smp_ops(msm_smp_ops),
+ .dt_compat = qcom_dt_match,
+MACHINE_END
+
+DT_MACHINE_START(APQ_DT, "Qualcomm (Flattened Device Tree)")
+ .dt_compat = apq8074_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-qcom/scm-boot.c b/arch/arm/mach-qcom/scm-boot.c
new file mode 100644
index 0000000..45cee3e
--- /dev/null
+++ b/arch/arm/mach-qcom/scm-boot.c
@@ -0,0 +1,39 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "scm.h"
+#include "scm-boot.h"
+
+/*
+ * Set the cold/warm boot address for one of the CPU cores.
+ */
+int scm_set_boot_addr(phys_addr_t addr, int flags)
+{
+ struct {
+ unsigned int flags;
+ phys_addr_t addr;
+ } cmd;
+
+ cmd.addr = addr;
+ cmd.flags = flags;
+ return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
+ &cmd, sizeof(cmd), NULL, 0);
+}
+EXPORT_SYMBOL(scm_set_boot_addr);
diff --git a/arch/arm/mach-qcom/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
new file mode 100644
index 0000000..7be32ff
--- /dev/null
+++ b/arch/arm/mach-qcom/scm-boot.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#ifndef __MACH_SCM_BOOT_H
+#define __MACH_SCM_BOOT_H
+
+#define SCM_BOOT_ADDR 0x1
+#define SCM_FLAG_COLDBOOT_CPU1 0x1
+#define SCM_FLAG_WARMBOOT_CPU1 0x2
+#define SCM_FLAG_WARMBOOT_CPU0 0x4
+
+int scm_set_boot_addr(phys_addr_t addr, int flags);
+
+#endif
diff --git a/arch/arm/mach-qcom/scm.c b/arch/arm/mach-qcom/scm.c
new file mode 100644
index 0000000..c536fd6
--- /dev/null
+++ b/arch/arm/mach-qcom/scm.c
@@ -0,0 +1,299 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/cacheflush.h>
+
+#include "scm.h"
+
+/* Cache line size for msm8x60 */
+#define CACHELINESIZE 32
+
+#define SCM_ENOMEM -5
+#define SCM_EOPNOTSUPP -4
+#define SCM_EINVAL_ADDR -3
+#define SCM_EINVAL_ARG -2
+#define SCM_ERROR -1
+#define SCM_INTERRUPTED 1
+
+static DEFINE_MUTEX(scm_lock);
+
+/**
+ * struct scm_command - one SCM command buffer
+ * @len: total available memory for command and response
+ * @buf_offset: start of command buffer
+ * @resp_hdr_offset: start of response buffer
+ * @id: command to be executed
+ * @buf: buffer returned from scm_get_command_buffer()
+ *
+ * An SCM command is laid out in memory as follows:
+ *
+ * ------------------- <--- struct scm_command
+ * | command header |
+ * ------------------- <--- scm_get_command_buffer()
+ * | command buffer |
+ * ------------------- <--- struct scm_response and
+ * | response header | scm_command_to_response()
+ * ------------------- <--- scm_get_response_buffer()
+ * | response buffer |
+ * -------------------
+ *
+ * There can be arbitrary padding between the headers and buffers so
+ * you should always use the appropriate scm_get_*_buffer() routines
+ * to access the buffers in a safe manner.
+ */
+struct scm_command {
+ u32 len;
+ u32 buf_offset;
+ u32 resp_hdr_offset;
+ u32 id;
+ u32 buf[0];
+};
+
+/**
+ * struct scm_response - one SCM response buffer
+ * @len: total available memory for response
+ * @buf_offset: start of response data relative to start of scm_response
+ * @is_complete: indicates if the command has finished processing
+ */
+struct scm_response {
+ u32 len;
+ u32 buf_offset;
+ u32 is_complete;
+};
+
+/**
+ * alloc_scm_command() - Allocate an SCM command
+ * @cmd_size: size of the command buffer
+ * @resp_size: size of the response buffer
+ *
+ * Allocate an SCM command, including enough room for the command
+ * and response headers as well as the command and response buffers.
+ *
+ * Returns a valid &scm_command on success or %NULL if the allocation fails.
+ */
+static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
+{
+ struct scm_command *cmd;
+ size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
+ resp_size;
+
+ cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
+ if (cmd) {
+ cmd->len = len;
+ cmd->buf_offset = offsetof(struct scm_command, buf);
+ cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
+ }
+ return cmd;
+}
+
+/**
+ * free_scm_command() - Free an SCM command
+ * @cmd: command to free
+ *
+ * Free an SCM command.
+ */
+static inline void free_scm_command(struct scm_command *cmd)
+{
+ kfree(cmd);
+}
+
+/**
+ * scm_command_to_response() - Get a pointer to a scm_response
+ * @cmd: command
+ *
+ * Returns a pointer to a response for a command.
+ */
+static inline struct scm_response *scm_command_to_response(
+ const struct scm_command *cmd)
+{
+ return (void *)cmd + cmd->resp_hdr_offset;
+}
+
+/**
+ * scm_get_command_buffer() - Get a pointer to a command buffer
+ * @cmd: command
+ *
+ * Returns a pointer to the command buffer of a command.
+ */
+static inline void *scm_get_command_buffer(const struct scm_command *cmd)
+{
+ return (void *)cmd->buf;
+}
+
+/**
+ * scm_get_response_buffer() - Get a pointer to a response buffer
+ * @rsp: response
+ *
+ * Returns a pointer to a response buffer of a response.
+ */
+static inline void *scm_get_response_buffer(const struct scm_response *rsp)
+{
+ return (void *)rsp + rsp->buf_offset;
+}
+
+static int scm_remap_error(int err)
+{
+ switch (err) {
+ case SCM_ERROR:
+ return -EIO;
+ case SCM_EINVAL_ADDR:
+ case SCM_EINVAL_ARG:
+ return -EINVAL;
+ case SCM_EOPNOTSUPP:
+ return -EOPNOTSUPP;
+ case SCM_ENOMEM:
+ return -ENOMEM;
+ }
+ return -EINVAL;
+}
+
+static u32 smc(u32 cmd_addr)
+{
+ int context_id;
+ register u32 r0 asm("r0") = 1;
+ register u32 r1 asm("r1") = (u32)&context_id;
+ register u32 r2 asm("r2") = cmd_addr;
+ do {
+ asm volatile(
+ __asmeq("%0", "r0")
+ __asmeq("%1", "r0")
+ __asmeq("%2", "r1")
+ __asmeq("%3", "r2")
+#ifdef REQUIRES_SEC
+ ".arch_extension sec\n"
+#endif
+ "smc #0 @ switch to secure world\n"
+ : "=r" (r0)
+ : "r" (r0), "r" (r1), "r" (r2)
+ : "r3");
+ } while (r0 == SCM_INTERRUPTED);
+
+ return r0;
+}
+
+static int __scm_call(const struct scm_command *cmd)
+{
+ int ret;
+ u32 cmd_addr = virt_to_phys(cmd);
+
+ /*
+ * Flush the entire cache here so callers don't have to remember
+ * to flush the cache when passing physical addresses to the secure
+ * side in the buffer.
+ */
+ flush_cache_all();
+ ret = smc(cmd_addr);
+ if (ret < 0)
+ ret = scm_remap_error(ret);
+
+ return ret;
+}
+
+/**
+ * scm_call() - Send an SCM command
+ * @svc_id: service identifier
+ * @cmd_id: command identifier
+ * @cmd_buf: command buffer
+ * @cmd_len: length of the command buffer
+ * @resp_buf: response buffer
+ * @resp_len: length of the response buffer
+ *
+ * Sends a command to the SCM and waits for the command to finish processing.
+ */
+int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
+ void *resp_buf, size_t resp_len)
+{
+ int ret;
+ struct scm_command *cmd;
+ struct scm_response *rsp;
+
+ cmd = alloc_scm_command(cmd_len, resp_len);
+ if (!cmd)
+ return -ENOMEM;
+
+ cmd->id = (svc_id << 10) | cmd_id;
+ if (cmd_buf)
+ memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
+
+ mutex_lock(&scm_lock);
+ ret = __scm_call(cmd);
+ mutex_unlock(&scm_lock);
+ if (ret)
+ goto out;
+
+ rsp = scm_command_to_response(cmd);
+ do {
+ u32 start = (u32)rsp;
+ u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
+ start &= ~(CACHELINESIZE - 1);
+ while (start < end) {
+ asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
+ : "memory");
+ start += CACHELINESIZE;
+ }
+ } while (!rsp->is_complete);
+
+ if (resp_buf)
+ memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
+out:
+ free_scm_command(cmd);
+ return ret;
+}
+EXPORT_SYMBOL(scm_call);
+
+u32 scm_get_version(void)
+{
+ int context_id;
+ static u32 version = -1;
+ register u32 r0 asm("r0");
+ register u32 r1 asm("r1");
+
+ if (version != -1)
+ return version;
+
+ mutex_lock(&scm_lock);
+
+ r0 = 0x1 << 8;
+ r1 = (u32)&context_id;
+ do {
+ asm volatile(
+ __asmeq("%0", "r0")
+ __asmeq("%1", "r1")
+ __asmeq("%2", "r0")
+ __asmeq("%3", "r1")
+#ifdef REQUIRES_SEC
+ ".arch_extension sec\n"
+#endif
+ "smc #0 @ switch to secure world\n"
+ : "=r" (r0), "=r" (r1)
+ : "r" (r0), "r" (r1)
+ : "r2", "r3");
+ } while (r0 == SCM_INTERRUPTED);
+
+ version = r1;
+ mutex_unlock(&scm_lock);
+
+ return version;
+}
+EXPORT_SYMBOL(scm_get_version);
diff --git a/arch/arm/mach-qcom/scm.h b/arch/arm/mach-qcom/scm.h
new file mode 100644
index 0000000..00b31ea
--- /dev/null
+++ b/arch/arm/mach-qcom/scm.h
@@ -0,0 +1,25 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#ifndef __MACH_SCM_H
+#define __MACH_SCM_H
+
+#define SCM_SVC_BOOT 0x1
+#define SCM_SVC_PIL 0x2
+
+extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
+ void *resp_buf, size_t resp_len);
+
+#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
+
+extern u32 scm_get_version(void);
+
+#endif
diff --git a/arch/arm/mach-qcom/smp.c b/arch/arm/mach-qcom/smp.c
new file mode 100644
index 0000000..67823a7
--- /dev/null
+++ b/arch/arm/mach-qcom/smp.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cputype.h>
+#include <asm/smp_plat.h>
+
+#include "scm-boot.h"
+
+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
+#define SCSS_CPU1CORE_RESET 0xD80
+#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
+
+extern void secondary_startup(void);
+
+static DEFINE_SPINLOCK(boot_lock);
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void __ref msm_cpu_die(unsigned int cpu)
+{
+ wfi();
+}
+#endif
+
+static inline int get_core_count(void)
+{
+ /* 1 + the PART[1:0] field of MIDR */
+ return ((read_cpuid_id() >> 4) & 3) + 1;
+}
+
+static void msm_secondary_init(unsigned int cpu)
+{
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+static void prepare_cold_cpu(unsigned int cpu)
+{
+ int ret;
+ ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
+ SCM_FLAG_COLDBOOT_CPU1);
+ if (ret == 0) {
+ void __iomem *sc1_base_ptr;
+ sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
+ if (sc1_base_ptr) {
+ writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
+ writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
+ writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
+ iounmap(sc1_base_ptr);
+ }
+ } else
+ printk(KERN_DEBUG "Failed to set secondary core boot "
+ "address\n");
+}
+
+static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ static int cold_boot_done;
+
+ /* Only need to bring cpu out of reset this way once */
+ if (cold_boot_done == false) {
+ prepare_cold_cpu(cpu);
+ cold_boot_done = true;
+ }
+
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * Send the secondary CPU a soft interrupt, thereby causing
+ * the boot monitor to read the system wide flags register,
+ * and branch to the address found there.
+ */
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system. The msm8x60
+ * does not support the ARM SCU, so just set the possible cpu mask to
+ * NR_CPUS.
+ */
+static void __init msm_smp_init_cpus(void)
+{
+ unsigned int i, ncores = get_core_count();
+
+ if (ncores > nr_cpu_ids) {
+ pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+ ncores, nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
+
+static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
+{
+}
+
+struct smp_operations msm_smp_ops __initdata = {
+ .smp_init_cpus = msm_smp_init_cpus,
+ .smp_prepare_cpus = msm_smp_prepare_cpus,
+ .smp_secondary_init = msm_secondary_init,
+ .smp_boot_secondary = msm_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = msm_cpu_die,
+#endif
+};
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH v2 4/5] clocksource: qcom: split building of legacy vs multiplatform support
From: Kumar Gala @ 2014-02-04 22:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391553532-27001-1-git-send-email-galak@codeaurora.org>
The majority of the clocksource code for the Qualcomm platform is shared
between newer (multiplatform) and older platforms. However there is a bit
of code that isn't, so only build it for the appropriate config.
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Kumar Gala <galak@codeaurora.org>
---
drivers/clocksource/qcom-timer.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c
index dca829e..e807acf 100644
--- a/drivers/clocksource/qcom-timer.c
+++ b/drivers/clocksource/qcom-timer.c
@@ -106,15 +106,6 @@ static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
return readl_relaxed(source_base + TIMER_COUNT_VAL);
}
-static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
-{
- /*
- * Shift timer count down by a constant due to unreliable lower bits
- * on some targets.
- */
- return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
-}
-
static struct clocksource msm_clocksource = {
.name = "dg_timer",
.rating = 300,
@@ -228,7 +219,7 @@ err:
sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
}
-#ifdef CONFIG_OF
+#ifdef CONFIG_ARCH_QCOM
static void __init msm_dt_timer_init(struct device_node *np)
{
u32 freq;
@@ -281,7 +272,7 @@ static void __init msm_dt_timer_init(struct device_node *np)
}
CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
-#endif
+#else
static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
u32 sts)
@@ -301,6 +292,15 @@ static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
return 0;
}
+static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
+{
+ /*
+ * Shift timer count down by a constant due to unreliable lower bits
+ * on some targets.
+ */
+ return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
+}
+
void __init msm7x01_timer_init(void)
{
struct clocksource *cs = &msm_clocksource;
@@ -327,3 +327,4 @@ void __init qsd8x50_timer_init(void)
return;
msm_timer_init(19200000 / 4, 32, 7, false);
}
+#endif
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox