* Re: powerpc: Fix missing includes needed for chroma
From: Jimi Xenidis @ 2013-11-21 17:49 UTC (permalink / raw)
To: Michael Neuling; +Cc: Yoonho Park, Linux PPC dev
[-- Attachment #1: Type: text/plain, Size: 3119 bytes --]
Drop it now :)
However, it may be nice to keep the A2 stuff until BGQ EOLs
-jx
On Wed, Nov 20, 2013 at 8:40 PM, Michael Neuling <mikey@neuling.org> wrote:
> chroma_defconfig is horribly broken currently, so add a bunch of
> #includes to fix it.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> ---
> So when are we dropping arch/powerpc/platforms/wsp?
>
> diff --git a/arch/powerpc/platforms/wsp/chroma.c
> b/arch/powerpc/platforms/wsp/chroma.c
> index 8ef53bc..aaa46b3 100644
> --- a/arch/powerpc/platforms/wsp/chroma.c
> +++ b/arch/powerpc/platforms/wsp/chroma.c
> @@ -15,6 +15,7 @@
> #include <linux/of.h>
> #include <linux/smp.h>
> #include <linux/time.h>
> +#include <linux/of_fdt.h>
>
> #include <asm/machdep.h>
> #include <asm/udbg.h>
> diff --git a/arch/powerpc/platforms/wsp/h8.c
> b/arch/powerpc/platforms/wsp/h8.c
> index d18e6cc..a3c87f3 100644
> --- a/arch/powerpc/platforms/wsp/h8.c
> +++ b/arch/powerpc/platforms/wsp/h8.c
> @@ -10,6 +10,7 @@
> #include <linux/kernel.h>
> #include <linux/of.h>
> #include <linux/io.h>
> +#include <linux/of_address.h>
>
> #include "wsp.h"
>
> diff --git a/arch/powerpc/platforms/wsp/ics.c
> b/arch/powerpc/platforms/wsp/ics.c
> index 2d3b1dd..3b782ce 100644
> --- a/arch/powerpc/platforms/wsp/ics.c
> +++ b/arch/powerpc/platforms/wsp/ics.c
> @@ -18,6 +18,8 @@
> #include <linux/smp.h>
> #include <linux/spinlock.h>
> #include <linux/types.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_address.h>
>
> #include <asm/io.h>
> #include <asm/irq.h>
> diff --git a/arch/powerpc/platforms/wsp/opb_pic.c
> b/arch/powerpc/platforms/wsp/opb_pic.c
> index cb565bf..3f67298 100644
> --- a/arch/powerpc/platforms/wsp/opb_pic.c
> +++ b/arch/powerpc/platforms/wsp/opb_pic.c
> @@ -15,6 +15,8 @@
> #include <linux/of.h>
> #include <linux/slab.h>
> #include <linux/time.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
>
> #include <asm/reg_a2.h>
> #include <asm/irq.h>
> diff --git a/arch/powerpc/platforms/wsp/psr2.c
> b/arch/powerpc/platforms/wsp/psr2.c
> index 508ec82..a87b414 100644
> --- a/arch/powerpc/platforms/wsp/psr2.c
> +++ b/arch/powerpc/platforms/wsp/psr2.c
> @@ -15,6 +15,7 @@
> #include <linux/of.h>
> #include <linux/smp.h>
> #include <linux/time.h>
> +#include <linux/of_fdt.h>
>
> #include <asm/machdep.h>
> #include <asm/udbg.h>
> diff --git a/arch/powerpc/platforms/wsp/scom_wsp.c
> b/arch/powerpc/platforms/wsp/scom_wsp.c
> index 8928507..6538b4d 100644
> --- a/arch/powerpc/platforms/wsp/scom_wsp.c
> +++ b/arch/powerpc/platforms/wsp/scom_wsp.c
> @@ -14,6 +14,7 @@
> #include <linux/of.h>
> #include <linux/spinlock.h>
> #include <linux/types.h>
> +#include <linux/of_address.h>
>
> #include <asm/cputhreads.h>
> #include <asm/reg_a2.h>
> diff --git a/arch/powerpc/platforms/wsp/wsp.c
> b/arch/powerpc/platforms/wsp/wsp.c
> index ddb6efe..58cd1f0 100644
> --- a/arch/powerpc/platforms/wsp/wsp.c
> +++ b/arch/powerpc/platforms/wsp/wsp.c
> @@ -13,6 +13,7 @@
> #include <linux/smp.h>
> #include <linux/delay.h>
> #include <linux/time.h>
> +#include <linux/of_address.h>
>
> #include <asm/scom.h>
>
>
[-- Attachment #2: Type: text/html, Size: 4027 bytes --]
^ permalink raw reply
* Re: [PATCH 24/34] PCI: use weak functions for MSI arch-specific functions
From: Thomas Petazzoni @ 2013-11-21 19:08 UTC (permalink / raw)
To: Ralf Baechle
Cc: Richard Zhu, linux-s390, linux-ia64, Tony Luck, Russell King,
Jason Cooper, Fenghua Yu, linux-mips, x86, Heiko Carstens,
Chris Metcalf, sparclinux, Ingo Molnar, Paul Mackerras,
H. Peter Anvin, Martin Schwidefsky, linux390, Thomas Gleixner,
linuxppc-dev, David S. Miller
In-Reply-To: <20131121173933.GT10382@linux-mips.org>
Dear Ralf Baechle,
On Thu, 21 Nov 2013 18:39:33 +0100, Ralf Baechle wrote:
> On Wed, Nov 20, 2013 at 10:50:43AM +0800, Richard Zhu wrote:
>
> Looking good,
>
> Acked-by: Ralf Baechle <ralf@linux-mips.org>
I think this patch was mistakenly sent by Richard Zhu. It is already
part of mainline since 3.12:
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/pci/msi.c?id=4287d824f265451cd10f6d20266b27a207a6cdd7.
Best regards,
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH 24/34] PCI: use weak functions for MSI arch-specific functions
From: Ralf Baechle @ 2013-11-21 19:33 UTC (permalink / raw)
To: Thomas Petazzoni
Cc: Richard Zhu, linux-s390, linux-ia64, Tony Luck, Russell King,
Jason Cooper, Fenghua Yu, linux-mips, x86, Heiko Carstens,
Chris Metcalf, sparclinux, Ingo Molnar, Paul Mackerras,
H. Peter Anvin, Martin Schwidefsky, linux390, Thomas Gleixner,
linuxppc-dev, David S. Miller
In-Reply-To: <20131121200804.617d6ae6@skate>
On Thu, Nov 21, 2013 at 08:08:04PM +0100, Thomas Petazzoni wrote:
> I think this patch was mistakenly sent by Richard Zhu. It is already
> part of mainline since 3.12:
Explains the deja vue ...
Ralf
^ permalink raw reply
* Re: [PATCH v2] offb: make the screen properties endian safe
From: Benjamin Herrenschmidt @ 2013-11-21 19:57 UTC (permalink / raw)
To: Cedric Le Goater; +Cc: linuxppc-dev
In-Reply-To: <528E2A89.90601@fr.ibm.com>
On Thu, 2013-11-21 at 16:45 +0100, Cedric Le Goater wrote:
> > - fbdev *generally* assume native endian framebuffer, but of course
> > under qemu today, the adapter will use a big endian frame buffer
> > aperture. You can compile in support for foreign endian but I don't know
> > how that actually works.
>
> OK. I will see how I can extend the tests. But, are you suggesting I should
> be using the foreign endian framework for the frame buffer ?
Well, if it works ... did you try 16 and 32bpp ?
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH v3] KVM: PPC: vfio kvm device: support spapr tce
From: Alex Williamson @ 2013-11-21 20:30 UTC (permalink / raw)
To: Alexey Kardashevskiy; +Cc: kvm-ppc, linuxppc-dev, linux-kernel, kvm
In-Reply-To: <528D6065.3030400@ozlabs.ru>
On Thu, 2013-11-21 at 12:22 +1100, Alexey Kardashevskiy wrote:
> On 11/21/2013 07:57 AM, Alex Williamson wrote:
> > On Wed, 2013-11-20 at 16:18 +1100, Alexey Kardashevskiy wrote:
> >> In addition to the external VFIO user API, a VFIO KVM device
> >> has been introduced recently.
> >>
> >> sPAPR TCE IOMMU is para-virtualized and the guest does map/unmap
> >> via hypercalls which take a logical bus id (LIOBN) as a target IOMMU
> >> identifier. LIOBNs are made up and linked to IOMMU groups by the user
> >> space. In order to accelerate IOMMU operations in the KVM, we need
> >> to tell KVM the information about LIOBN-to-group mapping.
> >>
> >> For that, a new KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE_LIOBN parameter
> >> is added. It accepts a pair of a VFIO group fd and LIOBN.
> >>
> >> This also adds a new kvm_vfio_find_group_by_liobn() function which
> >> receives kvm struct, LIOBN and a callback. As it increases the IOMMU
> >> group use counter, the KVMr is required to pass a callback which
> >> called when the VFIO group is about to be removed VFIO-KVM tracking so
> >> the KVM is able to call iommu_group_put() to release the IOMMU group.
> >>
> >> The KVM uses kvm_vfio_find_group_by_liobn() once per KVM run and caches
> >> the result in kvm_arch. iommu_group_put() for all groups will be called
> >> when KVM finishes (in the SPAPR TCE in KVM enablement patch).
> >>
> >> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> >> ---
> >> Changes:
> >> v3:
> >> * total rework
> >> * added a release callback into kvm_vfio_find_group_by_liobn so now
> >> the user of the API can get a notification if the group is about to
> >> disappear
> >> ---
> >> Documentation/virtual/kvm/devices/vfio.txt | 19 ++++-
> >> arch/powerpc/kvm/Kconfig | 1 +
> >> arch/powerpc/kvm/Makefile | 3 +
> >> include/linux/kvm_host.h | 18 +++++
> >> include/uapi/linux/kvm.h | 7 ++
> >> virt/kvm/vfio.c | 116 ++++++++++++++++++++++++++++-
> >> 6 files changed, 161 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/Documentation/virtual/kvm/devices/vfio.txt b/Documentation/virtual/kvm/devices/vfio.txt
> >> index ef51740..7ecb3b2 100644
> >> --- a/Documentation/virtual/kvm/devices/vfio.txt
> >> +++ b/Documentation/virtual/kvm/devices/vfio.txt
> >> @@ -16,7 +16,22 @@ Groups:
> >>
> >> KVM_DEV_VFIO_GROUP attributes:
> >> KVM_DEV_VFIO_GROUP_ADD: Add a VFIO group to VFIO-KVM device tracking
> >> + kvm_device_attr.addr points to an int32_t file descriptor
> >> + for the VFIO group.
> >> +
> >> KVM_DEV_VFIO_GROUP_DEL: Remove a VFIO group from VFIO-KVM device tracking
> >> + kvm_device_attr.addr points to an int32_t file descriptor
> >> + for the VFIO group.
> >> +
> >> + KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE_LIOBN: sets a liobn for a VFIO group
> >> + kvm_device_attr.addr points to a struct:
> >> + struct kvm_vfio_spapr_tce_liobn {
> >> + __u32 argsz;
> >> + __u32 fd;
> >
> > fds are signed, __s32
> >
> >> + __u32 liobn;
> >> + };
> >> + where
> >> + @argsz is a struct size;
> >> + @fd is a file descriptor for a VFIO group;
> >> + @liobn is a logical bus id to be associated with the group.
> >>
> >> -For each, kvm_device_attr.addr points to an int32_t file descriptor
> >> -for the VFIO group.
> >> diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
> >> index 61b3535..d1b7f64 100644
> >> --- a/arch/powerpc/kvm/Kconfig
> >> +++ b/arch/powerpc/kvm/Kconfig
> >> @@ -60,6 +60,7 @@ config KVM_BOOK3S_64
> >> select KVM_BOOK3S_64_HANDLER
> >> select KVM
> >> select SPAPR_TCE_IOMMU
> >> + select KVM_VFIO
> >> ---help---
> >> Support running unmodified book3s_64 and book3s_32 guest kernels
> >> in virtual machines on book3s_64 host processors.
> >> diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
> >> index 6646c95..2438d2e 100644
> >> --- a/arch/powerpc/kvm/Makefile
> >> +++ b/arch/powerpc/kvm/Makefile
> >> @@ -87,6 +87,9 @@ kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \
> >> kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \
> >> book3s_xics.o
> >>
> >> +kvm-book3s_64-objs-$(CONFIG_KVM_VFIO) += \
> >> + $(KVM)/vfio.o \
> >> +
> >> kvm-book3s_64-module-objs := \
> >> $(KVM)/kvm_main.o \
> >> $(KVM)/eventfd.o \
> >> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> >> index 88ff96a..1d2ad5e 100644
> >> --- a/include/linux/kvm_host.h
> >> +++ b/include/linux/kvm_host.h
> >> @@ -1112,5 +1112,23 @@ static inline bool kvm_vcpu_eligible_for_directed_yield(struct kvm_vcpu *vcpu)
> >> }
> >>
> >> #endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
> >> +
> >> +typedef void (*kvm_vfio_release_group_callback)(struct kvm *kvm,
> >> + unsigned long liobn);
> >
> > liobn was said to be __u32 in kvm_vfio_spapr_tce_liobn above, here it's
> > unsigned long?
>
>
> PAPR spec says it is 32 bit and kvm_vfio_spapr_tce_liobn is a binary
> interface (ABI?) so I want it to be precise.
>
> However kvmppc_get_gpr() (used to parse hypercall parameters such as liobn)
> return unsigned long. So inside the kernel I use unsigned long.
>
> So what does make sense to change here?
Perhaps nothing if that's clear to those familiar with PAPR. Thanks,
Alex
> >
> >> +
> >> +#if defined(CONFIG_KVM_VFIO) && defined(CONFIG_SPAPR_TCE_IOMMU)
> >> +
> >> +extern struct iommu_group *kvm_vfio_find_group_by_liobn(struct kvm *kvm,
> >> + unsigned long liobn, kvm_vfio_release_group_callback cb);
> >> +
> >> +#else
> >> +
> >> +static inline struct iommu_group *kvm_vfio_find_group_by_liobn(struct kvm *kvm,
> >> + unsigned long liobn, ikvm_vfio_release_group_callback cb)
> >> +{
> >> + return NULL;
> >> +}
> >> +#endif /* CONFIG_KVM_VFIO && CONFIG_SPAPR_TCE_IOMMU */
> >> +
> >> #endif
> >>
> >> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> >> index 7c1a349..3d77dde 100644
> >> --- a/include/uapi/linux/kvm.h
> >> +++ b/include/uapi/linux/kvm.h
> >> @@ -847,6 +847,13 @@ struct kvm_device_attr {
> >> #define KVM_DEV_VFIO_GROUP 1
> >> #define KVM_DEV_VFIO_GROUP_ADD 1
> >> #define KVM_DEV_VFIO_GROUP_DEL 2
> >> +#define KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE_LIOBN 3
> >> +
> >> +struct kvm_vfio_spapr_tce_liobn {
> >> + __u32 argsz;
> >> + __u32 fd;
> >> + __u32 liobn;
> >> +};
> >>
> >> /*
> >> * ioctls for VM fds
> >> diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c
> >> index ca4260e..448910d 100644
> >> --- a/virt/kvm/vfio.c
> >> +++ b/virt/kvm/vfio.c
> >> @@ -22,6 +22,12 @@
> >> struct kvm_vfio_group {
> >> struct list_head node;
> >> struct vfio_group *vfio_group;
> >> +#ifdef CONFIG_SPAPR_TCE_IOMMU
> >> + struct {
> >> + unsigned long liobn;
> >> + kvm_vfio_release_group_callback cb;
> >> + } spapr_tce;
> >> +#endif
> >> };
> >>
> >> struct kvm_vfio {
> >> @@ -59,6 +65,51 @@ static void kvm_vfio_group_put_external_user(struct vfio_group *vfio_group)
> >> symbol_put(vfio_group_put_external_user);
> >> }
> >>
> >> +#ifdef CONFIG_SPAPR_TCE_IOMMU
> >> +struct iommu_group *kvm_vfio_find_group_by_liobn(struct kvm *kvm,
> >> + unsigned long liobn, kvm_vfio_release_group_callback cb)
> >> +{
> >> + struct kvm_vfio_group *kvg;
> >> + int group_id;
> >> + struct iommu_group *grp;
> >> + struct kvm_vfio *kv = NULL;
> >> + struct kvm_device *tmp;
> >> +
> >> + if (!cb)
> >> + return NULL;
> >
> > Is it worthwhile to use ERR_PTR(-EINVAL) here and the caller can use
> > IS_ERR()?
> >
> >> +
> >> + /* Find a VFIO KVM device */
> >> + list_for_each_entry(tmp, &kvm->devices, vm_node) {
> >> + if (tmp->ops != &kvm_vfio_ops)
> >> + continue;
> >> +
> >> + kv = tmp->private;
> >> + break;
> >> + }
> >> +
> >> + if (!kv)
> >> + return NULL;
> >
> > ERR_PTR(-EFAULT)? EIO?
> >
> >> +
> >> + /* Find a group */
> >
> > Still ignoring kv->lock
> >
> >> + list_for_each_entry(kvg, &kv->group_list, node) {
> >> + if (kvg->spapr_tce.liobn != liobn)
> >> + continue;
> >> +
> >> + if (kvg->spapr_tce.cb)
> >> + return NULL;
> >
> > ERR_PTR(-EBUSY)?
> >
> >> +
> >> + kvg->spapr_tce.cb = cb;
> >> + group_id = vfio_external_user_iommu_id(kvg->vfio_group);
> >> + grp = iommu_group_get_by_id(group_id);
> >> +
> >> + return grp;
> >> + }
> >> +
> >> + return NULL;
> >
> > ERR_PTR(-ENODEV)?
> >
> >> +}
> >> +EXPORT_SYMBOL_GPL(kvm_vfio_find_group_by_liobn);
> >> +#endif
> >> +
> >> /*
> >> * Groups can use the same or different IOMMU domains. If the same then
> >> * adding a new group may change the coherency of groups we've previously
> >> @@ -170,6 +221,11 @@ static int kvm_vfio_set_group(struct kvm_device *dev, long attr, u64 arg)
> >> continue;
> >>
> >> list_del(&kvg->node);
> >> +#ifdef CONFIG_SPAPR_TCE_IOMMU
> >> + if (kvg->spapr_tce.cb)
> >> + kvg->spapr_tce.cb(dev->kvm,
> >> + kvg->spapr_tce.liobn);
> >> +#endif
> >> kvm_vfio_group_put_external_user(kvg->vfio_group);
> >> kfree(kvg);
> >> ret = 0;
> >> @@ -183,6 +239,62 @@ static int kvm_vfio_set_group(struct kvm_device *dev, long attr, u64 arg)
> >> kvm_vfio_update_coherency(dev);
> >>
> >> return ret;
> >> +
> >> +#ifdef CONFIG_SPAPR_TCE_IOMMU
> >> + case KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE_LIOBN: {
> >> + struct kvm_vfio_spapr_tce_liobn param;
> >> + unsigned long minsz;
> >> + struct kvm_vfio *kv = dev->private;
> >> + struct vfio_group *vfio_group;
> >> + struct kvm_vfio_group *kvg;
> >> + struct fd f;
> >> +
> >> + minsz = offsetofend(struct kvm_vfio_spapr_tce_liobn, liobn);
> >> +
> >> + if (copy_from_user(¶m, (void __user *)arg, minsz))
> >> + return -EFAULT;
> >> +
> >> + if (param.argsz < minsz)
> >> + return -EINVAL;
> >> +
> >> + if (copy_from_user(¶m, (void __user *)arg, minsz))
> >> + return -EFAULT;
> >
> > copy_from_user twice? Extra copy here?
>
>
> Oh. All I wanted was to read minsz first but I cut-n-pasted too blindely :)
>
> >
> >> +
> >> + f = fdget(param.fd);
> >> + if (!f.file)
> >> + return -EBADF;
> >> +
> >> + vfio_group = kvm_vfio_group_get_external_user(f.file);
> >> + fdput(f);
> >> +
> >> + if (IS_ERR(vfio_group))
> >> + return PTR_ERR(vfio_group);
> >> +
> >> + ret = -ENOENT;
> >> +
> >> + mutex_lock(&kv->lock);
> >> +
> >> + list_for_each_entry(kvg, &kv->group_list, node) {
> >> + if (kvg->vfio_group != vfio_group)
> >> + continue;
> >> +
> >> + if (kvg->spapr_tce.liobn) {
> >> + ret = -EBUSY;
> >> + break;
> >> + }
> >
> > Is zero not an liobn that can be used by userspace?
>
> Good point, thanks. I thought zero cannot be used but by spec -1 is reserved
>
>
> > Is it intentional
> > that there's no way to unset or change the group/liobn mapping? Thanks,
>
>
> I do not see why we would want to disable once enabled acceleration. Group
> removal should clear it though so we are good.
>
> Thanks for the review and patience :)
>
>
> >
> > Alex
> >
> >> +
> >> + kvg->spapr_tce.liobn = param.liobn;
> >> + ret = 0;
> >> + break;
> >> + }
> >> +
> >> + mutex_unlock(&kv->lock);
> >> +
> >> + kvm_vfio_group_put_external_user(vfio_group);
> >> +
> >> + return ret;
> >> + }
> >> +#endif /* CONFIG_SPAPR_TCE_IOMMU */
> >> }
> >>
> >> return -ENXIO;
> >> @@ -207,9 +319,11 @@ static int kvm_vfio_has_attr(struct kvm_device *dev,
> >> switch (attr->attr) {
> >> case KVM_DEV_VFIO_GROUP_ADD:
> >> case KVM_DEV_VFIO_GROUP_DEL:
> >> +#ifdef CONFIG_SPAPR_TCE_IOMMU
> >> + case KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE_LIOBN:
> >> +#endif
> >> return 0;
> >> }
> >> -
> >> break;
> >> }
> >>
> >
> >
> >
>
>
^ permalink raw reply
* Re: [PATCH 0/9 v2] vfio-pci: add support for Freescale IOMMU (PAMU)
From: Alex Williamson @ 2013-11-21 20:43 UTC (permalink / raw)
To: Bharat Bhushan
Cc: linux-pci@vger.kernel.org, joro@8bytes.org, agraf@suse.de,
Stuart Yoder, Scott Wood, iommu@lists.linux-foundation.org,
bhelgaas@google.com, linuxppc-dev@lists.ozlabs.org,
linux-kernel@vger.kernel.org
In-Reply-To: <6A3DF150A5B70D4F9B66A25E3F7C888D0721D9AC@039-SN2MPN1-012.039d.mgd.msft.net>
On Thu, 2013-11-21 at 11:20 +0000, Bharat Bhushan wrote:
>
> > -----Original Message-----
> > From: Alex Williamson [mailto:alex.williamson@redhat.com]
> > Sent: Thursday, November 21, 2013 12:17 AM
> > To: Bhushan Bharat-R65777
> > Cc: joro@8bytes.org; bhelgaas@google.com; agraf@suse.de; Wood Scott-B07421;
> > Yoder Stuart-B08248; iommu@lists.linux-foundation.org; linux-
> > pci@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; linux-
> > kernel@vger.kernel.org; Bhushan Bharat-R65777
> > Subject: Re: [PATCH 0/9 v2] vfio-pci: add support for Freescale IOMMU (PAMU)
> >
> > On Tue, 2013-11-19 at 10:47 +0530, Bharat Bhushan wrote:
> > > From: Bharat Bhushan <bharat.bhushan@freescale.com>
> > >
> > > PAMU (FSL IOMMU) has a concept of primary window and subwindows.
> > > Primary window corresponds to the complete guest iova address space
> > > (including MSI space), with respect to IOMMU_API this is termed as
> > > geometry. IOVA Base of subwindow is determined from the number of
> > > subwindows (configurable using iommu API).
> > > MSI I/O page must be within the geometry and maximum supported
> > > subwindows, so MSI IO-page is setup just after guest memory iova space.
> > >
> > > So patch 1/9-4/9(inclusive) are for defining the interface to get:
> > > - Number of MSI regions (which is number of MSI banks for powerpc)
> > > - MSI-region address range: Physical page which have the
> > > address/addresses used for generating MSI interrupt
> > > and size of the page.
> > >
> > > Patch 5/9-7/9(inclusive) is defining the interface of setting up MSI
> > > iova-base for a msi region(bank) for a device. so that when
> > > msi-message will be composed then this configured iova will be used.
> > > Earlier we were using iommu interface for getting the configured iova
> > > which was not currect and Alex Williamson suggeested this type of interface.
> > >
> > > patch 8/9 moves some common functions in a separate file so that these
> > > can be used by FSL_PAMU implementation (next patch uses this).
> > > These will be used later for iommu-none implementation. I believe we
> > > can do more of this but will take step by step.
> > >
> > > Finally last patch actually adds the support for FSL-PAMU :)
> >
> > Patches 1-3: msi_get_region needs to return an error an error (probably
> > -EINVAL) if called on a path where there's no backend implementation.
> > Otherwise the caller doesn't know that the data in the region pointer isn't
> > valid.
>
> will correct.
>
> >
> > Patches 5&6: same as above for msi_set_iova, return an error if no backend
> > implementation.
>
> Ok
>
> >
> > Patch 7: Why does fsl_msi_del_iova_device bother to return anything if it's
> > always zero? Return -ENODEV when not found?
>
> Will make -ENODEV.
>
> >
> > Patch 9:
> >
> > vfio_handle_get_attr() passes random kernel data back to userspace in the event
> > of iommu_domain_get_attr() error.
>
> Will correct.
>
> >
> > vfio_handle_set_attr(): I don't see any data validation happening, is
> > iommu_domain_set_attr() really that safe?
>
> We do not need any data validation here and iommu driver does whatever needed.
> So yes, iommu_domain_set_attr() is safe.
>
> >
> > For both of those, drop the pr_err on unknown attribute, it's sufficient to
> > return error.
>
> ok
>
> >
> > Is VFIO_IOMMU_PAMU_GET_MSI_BANK_COUNT per aperture (ie. each vfio user has
> > $COUNT regions at their disposal exclusively)?
>
> Number of msi-bank count is system wide and not per aperture, But will be setting windows for banks in the device aperture.
> So say if we are direct assigning 2 pci device (both have different iommu group, so 2 aperture in iommu) to VM.
> Now qemu can make only one call to know how many msi-banks are there but it must set sub-windows for all banks for both pci device in its respective aperture.
I'm still confused. What I want to make sure of is that the banks are
independent per aperture. For instance, if we have two separate
userspace processes operating independently and they both chose to use
msi bank zero for their device, that's bank zero within each aperture
and doesn't interfere. Or another way to ask is can a malicious user
interfere with other users by using the wrong bank. Thanks,
Alex
^ permalink raw reply
* Re: [PATCH 0/9 v2] vfio-pci: add support for Freescale IOMMU (PAMU)
From: Scott Wood @ 2013-11-21 20:47 UTC (permalink / raw)
To: Alex Williamson
Cc: linux-pci@vger.kernel.org, agraf@suse.de, Stuart Yoder,
Bharat Bhushan, iommu@lists.linux-foundation.org,
bhelgaas@google.com, linuxppc-dev@lists.ozlabs.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1385066603.2879.414.camel@ul30vt.home>
On Thu, 2013-11-21 at 13:43 -0700, Alex Williamson wrote:
> On Thu, 2013-11-21 at 11:20 +0000, Bharat Bhushan wrote:
> >
> > > -----Original Message-----
> > > From: Alex Williamson [mailto:alex.williamson@redhat.com]
> > > Sent: Thursday, November 21, 2013 12:17 AM
> > > To: Bhushan Bharat-R65777
> > > Cc: joro@8bytes.org; bhelgaas@google.com; agraf@suse.de; Wood Scott-B07421;
> > > Yoder Stuart-B08248; iommu@lists.linux-foundation.org; linux-
> > > pci@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; linux-
> > > kernel@vger.kernel.org; Bhushan Bharat-R65777
> > > Subject: Re: [PATCH 0/9 v2] vfio-pci: add support for Freescale IOMMU (PAMU)
> > >
> > > Is VFIO_IOMMU_PAMU_GET_MSI_BANK_COUNT per aperture (ie. each vfio user has
> > > $COUNT regions at their disposal exclusively)?
> >
> > Number of msi-bank count is system wide and not per aperture, But will be setting windows for banks in the device aperture.
> > So say if we are direct assigning 2 pci device (both have different iommu group, so 2 aperture in iommu) to VM.
> > Now qemu can make only one call to know how many msi-banks are there but it must set sub-windows for all banks for both pci device in its respective aperture.
>
> I'm still confused. What I want to make sure of is that the banks are
> independent per aperture. For instance, if we have two separate
> userspace processes operating independently and they both chose to use
> msi bank zero for their device, that's bank zero within each aperture
> and doesn't interfere. Or another way to ask is can a malicious user
> interfere with other users by using the wrong bank. Thanks,
They can interfere. With this hardware, the only way to prevent that is
to make sure that a bank is not shared by multiple protection contexts.
For some of our users, though, I believe preventing this is less
important than the performance benefit.
-Scott
^ permalink raw reply
* Re: [PATCH 0/9 v2] vfio-pci: add support for Freescale IOMMU (PAMU)
From: Alex Williamson @ 2013-11-21 21:00 UTC (permalink / raw)
To: Scott Wood
Cc: linux-pci@vger.kernel.org, agraf@suse.de, Stuart Yoder,
Bharat Bhushan, iommu@lists.linux-foundation.org,
bhelgaas@google.com, linuxppc-dev@lists.ozlabs.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1385066835.1403.489.camel@snotra.buserror.net>
On Thu, 2013-11-21 at 14:47 -0600, Scott Wood wrote:
> On Thu, 2013-11-21 at 13:43 -0700, Alex Williamson wrote:
> > On Thu, 2013-11-21 at 11:20 +0000, Bharat Bhushan wrote:
> > >
> > > > -----Original Message-----
> > > > From: Alex Williamson [mailto:alex.williamson@redhat.com]
> > > > Sent: Thursday, November 21, 2013 12:17 AM
> > > > To: Bhushan Bharat-R65777
> > > > Cc: joro@8bytes.org; bhelgaas@google.com; agraf@suse.de; Wood Scott-B07421;
> > > > Yoder Stuart-B08248; iommu@lists.linux-foundation.org; linux-
> > > > pci@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; linux-
> > > > kernel@vger.kernel.org; Bhushan Bharat-R65777
> > > > Subject: Re: [PATCH 0/9 v2] vfio-pci: add support for Freescale IOMMU (PAMU)
> > > >
> > > > Is VFIO_IOMMU_PAMU_GET_MSI_BANK_COUNT per aperture (ie. each vfio user has
> > > > $COUNT regions at their disposal exclusively)?
> > >
> > > Number of msi-bank count is system wide and not per aperture, But will be setting windows for banks in the device aperture.
> > > So say if we are direct assigning 2 pci device (both have different iommu group, so 2 aperture in iommu) to VM.
> > > Now qemu can make only one call to know how many msi-banks are there but it must set sub-windows for all banks for both pci device in its respective aperture.
> >
> > I'm still confused. What I want to make sure of is that the banks are
> > independent per aperture. For instance, if we have two separate
> > userspace processes operating independently and they both chose to use
> > msi bank zero for their device, that's bank zero within each aperture
> > and doesn't interfere. Or another way to ask is can a malicious user
> > interfere with other users by using the wrong bank. Thanks,
>
> They can interfere. With this hardware, the only way to prevent that is
> to make sure that a bank is not shared by multiple protection contexts.
> For some of our users, though, I believe preventing this is less
> important than the performance benefit.
I think we need some sort of ownership model around the msi banks then.
Otherwise there's nothing preventing another userspace from attempting
an MSI based attack on other users, or perhaps even on the host. VFIO
can't allow that. Thanks,
Alex
^ permalink raw reply
* Re: [PATCH v2] panic: Make panic_timeout configurable
From: Jason Baron @ 2013-11-21 21:21 UTC (permalink / raw)
To: Michael Ellerman
Cc: Felipe Contreras, linux-kernel@vger.kernel.org,
ralf@linux-mips.org, paulus@samba.org, Andrew Morton,
linuxppc-dev@lists.ozlabs.org, Ingo Molnar
In-Reply-To: <20131121111638.GA15913@concordia>
On 11/21/2013 06:16 AM, Michael Ellerman wrote:
> On Tue, Nov 19, 2013 at 05:04:14PM -0500, Jason Baron wrote:
>> On 11/19/2013 02:09 AM, Ingo Molnar wrote:
>>>
>>> * Jason Baron <jbaron@akamai.com> wrote:
>>>
>>>> On 11/18/2013 05:30 PM, Andrew Morton wrote:
>>>>> On Mon, 18 Nov 2013 21:04:36 +0000 (GMT) Jason Baron <jbaron@akamai.com> wrote:
>>>>>
>>>>>> The panic_timeout value can be set via the command line option 'panic=x', or via
>>>>>> /proc/sys/kernel/panic, however that is not sufficient when the panic occurs
>>>>>> before we are able to set up these values. Thus, add a CONFIG_PANIC_TIMEOUT
>>>>>> so that we can set the desired value from the .config.
>>>>>>
>>>>>> The default panic_timeout value continues to be 0 - wait forever,
>>>>>> except for powerpc and mips, which have been defaulted to 180 and
>>>>>> 5 respectively. This is in keeping with the fact that these
>>>>>> arches already set panic_timeout in their arch init code.
>>>>>> However, I found three exceptions- two in mips and one in powerpc
>>>>>> where the settings didn't match these default values. In those
>>>>>> cases, I left the arch code so it continues to override, in case
>>>>>> the user has not changed from the default. It would nice if these
>>>>>> arches had one default value, or if we could determine the
>>>>>> correct setting at compile-time.
> ...
>>
>> Sure, I can round up all the related patches in this area that make
>> sense and re-submit as a series.
>>
>> Felipe, would the CONFIG_PANIC_TIMEOUT=xx .config parameter work for your
>> needs, or would you still like to see the command-line processing moved
>> up?
>>
>> I'd also like to hear from the PowerPC folks about the arch defaults
>> there. Now, that mips is ok with CONFIG_PANIC_TIMEOUT, PowerPC is the
>> only arch doing specific initialization of 'panic_timeout'.
>
> Hi Jason,
>
> I think we'd like to choose the value at runtime, as we do now. The
> powerpc arch supports a wide spread of different hardware, so it's nice
> to be able to customise the value based on the platform. Also we build a
> single kernel that boots on many platforms, and so we can't pick the
> value at compile time.
>
> cheers
>
Hi,
Ok, So powerpc sets the timeout to '180' during setup_arch(), but then
overrides the value to '10' only for pSeries. The patch proposed in this
thread, sets the default built-in value for powerpc to 180 and then
continues to override in pSeries, if its still 180 (IE the user hasn't
requested another value). This allows the panic_timeout value to have
an effect before we reach the arch_init() code. Are you ok with this?
That is, are you ok with the proposed powerpc bits?
Or should we drop the powerpc default 180 Kconfig setting, such that
it continues to be 0 until the arch code is run? And in that case
only apply the arch defaults if still 0.
Thanks,
-Jason
^ permalink raw reply
* Re: [PATCH 2/2] powerpc: mm: change pgtable index size for 64K page
From: Paul Mackerras @ 2013-11-21 22:11 UTC (permalink / raw)
To: Liu Ping Fan; +Cc: linuxppc-dev
In-Reply-To: <1385000275-5988-2-git-send-email-pingfank@linux.vnet.ibm.com>
On Thu, Nov 21, 2013 at 10:17:55AM +0800, Liu Ping Fan wrote:
> For 64K page, we waste half of the pte_t page. With this patch, after
> changing PGD_INDEX_SIZE from 12 to 11, PTE_INDEX_SIZE from 8 to 9,
> we can improve the usage of pte_t page and shrink the continuous phys
> size for pgd_t.
>
> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/pgtable-ppc64-64k.h | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
> index a56b82f..f6955ff 100644
> --- a/arch/powerpc/include/asm/pgtable-ppc64-64k.h
> +++ b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
> @@ -4,10 +4,10 @@
> #include <asm-generic/pgtable-nopud.h>
>
>
> -#define PTE_INDEX_SIZE 8
> +#define PTE_INDEX_SIZE 9
> #define PMD_INDEX_SIZE 10
> #define PUD_INDEX_SIZE 0
> -#define PGD_INDEX_SIZE 12
> +#define PGD_INDEX_SIZE 11
Nack. Those definitions are the way they are in order to have the PMD
map 16MB, which is our large page size, so that transparent huge pages
work.
Paul.
^ permalink raw reply
* Re: [PATCH] powerpc/signals: Mark VSX not saved with small contexts
From: Michael Neuling @ 2013-11-21 22:21 UTC (permalink / raw)
To: Carlos O'Donell
Cc: Michael Ellerman, Steve Best, linuxppc-dev, Haren Myneni
In-Reply-To: <528E2EB6.2010003@redhat.com>
Carlos O'Donell <carlos@redhat.com> wrote:
> On 11/21/2013 06:33 AM, Michael Ellerman wrote:
> > On Wed, Nov 20, 2013 at 04:18:54PM +1100, Michael Neuling wrote:
> >> The VSX MSR bit in the user context indicates if the context contains VSX
> >> state. Currently we set this when the process has touched VSX at any stage.
> >>
> >> Unfortunately, if the user has not provided enough space to save the VSX state,
> >> we can't save it but we currently still set the MSR VSX bit.
> >>
> >> This patch changes this to clear the MSR VSX bit when the user doesn't provide
> >> enough space. This indicates that there is no valid VSX state in the user
> >> context.
> >>
> >> This is needed to support get/set/make/swapcontext for applications that use
> >> VSX but only provide a small context. For example, getcontext in glibc
> >> provides a smaller context since the VSX registers don't need to be saved over
> >> the glibc function call. But since the program calling getcontext may have
> >> used VSX, the kernel currently says the VSX state is valid when it's not. If
> >> the returned context is then used in setcontext (ie. a small context without
> >> VSX but with MSR VSX set), the kernel will refuse the context. This situation
> >> has been reported by the glibc community.
> >
> > Broken since forever?
>
> Yes, broken since forever. At least it was known in glibc 2.18 that this was
> broken, but without an active distribution using it the defect wasn't analyzed.
>
> >> Tested-by: Haren Myneni <haren@linux.vnet.ibm.com>
> >> Signed-off-by: Michael Neuling <mikey@neuling.org>
> >> Cc: stable@vger.kernel.org
> >> ---
> >> arch/powerpc/kernel/signal_32.c | 10 +++++++++-
> >
> > What about the 64-bit code? I don't know the code but it appears at a glance to
> > have the same bug.
>
> It doesn't happen with 64-bit code because there the context contains
> a sigcontext which on ppc64 has vmx_reserve to store the entire VMX
> state. Therefore 64-bit ppc always has space to store the VMX registers
> in a userspace context switch. It is only the 32-bit ppc ABI that lacks
> the space.
VMX? I don't understand this at all. We extended the ucontext to
handle the extra VSX state, so older code may still be using the small
ucontext and we already have a bunch of checks in the 64bit case for
this.
I agree with Michael, we should add this to the 64 bit case. If we
can't put VSX state in, then clear MSR VSX.
>
> >> diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
> >> index 749778e..1844298 100644
> >> --- a/arch/powerpc/kernel/signal_32.c
> >> +++ b/arch/powerpc/kernel/signal_32.c
> >> @@ -457,7 +457,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
> >> if (copy_vsx_to_user(&frame->mc_vsregs, current))
> >> return 1;
> >> msr |= MSR_VSX;
> >> - }
> >> + } else if (!ctx_has_vsx_region)
> >> + /*
> >> + * With a small context structure we can't hold the VSX
> >> + * registers, hence clear the MSR value to indicate the state
> >> + * was not saved.
> >> + */
> >> + msr &= ~MSR_VSX;
> >
> > I think it'd be clearer if this was just the else case. The full context is:
> >
> > if (current->thread.used_vsr && ctx_has_vsx_region) {
> > __giveup_vsx(current);
> > if (copy_vsx_to_user(&frame->mc_vsregs, current))
> > return 1;
> > msr |= MSR_VSX;
> > + } else if (!ctx_has_vsx_region)
> > + /*
> > + * With a small context structure we can't hold the VSX
> > + * registers, hence clear the MSR value to indicate the state
> > + * was not saved.
> > + */
> > + msr &= ~MSR_VSX;
> >
> > Which means if current->thread.user_vsr and ctx_has_vsx_region are both false
> > we potentially leave MSR_VSX set in msr. I think it should be the case that
> > MSR_VSX is only ever set if current->thread.used_vsr is true, so it should be
> > OK in pratice, but it seems unnecessarily fragile.
>
> If current->thread.user_vsr and ctx_has_vsx_region are both false then
> !ctx_has_vsx_region is true and we clear MSR_VSX.
>
> Perhaps you mean if current->thread.user_vsr is false, but ctx_has_vsx_region
> is true?
>
> Previously the else clause reset MSR_VSX if:
> 1. current->thread.used_vsr == 0 && ctx_has_vsx_region == 0
> 2. current->thread.used_vsr == 1 && ctx_has_vsx_region == 0,
>
> Now it resets MSR_VSX additionally for:
> 3. current->thread.used_vsr == 0 && ctx_has_vsx_region == 1,
>
> 3. is a valid state. The task has not touched the VSX state and the context
> is large enough to be saved into. This may be a future state for ppc32 if
> we adjust the ABI to have a large enough context buffer. However at present
> it's not a plausible state. It's also a "don't care" state since there is
> nothing saved in the context, and if nothing was saved in the context then
> MSR_VSX is not set.
This makes my head hurt.
MSR VSX needs to be cleared always if there is no VSX region. It's
independant of used_vsr, so let's make that clear in the code.
>
> > The logic should be "if we write VSX we set MSR_VSX, else we clear MSR_VSX", ie:
> >
> > if (current->thread.used_vsr && ctx_has_vsx_region) {
> > __giveup_vsx(current);
> > if (copy_vsx_to_user(&frame->mc_vsregs, current))
> > return 1;
> > msr |= MSR_VSX;
> > } else
> > msr &= ~MSR_VSX;
>
> If anything I dislike this because it might mask a bug in earlier code that
> might erroneously set MSR_VSX even though current->thread.user_vsr is not
> true. If anything the extra state 3. covered here is a buggy state.
>
> I agree that your suggestion is more robust though since the definition of
> robustness is to operate despite failures.
The basic idea of the patch is that if the user hasn't passed a VSX
region, then we clear MSR VSX to indicate there is no VSX data.
It's independant of used_vsr.
So how about we make it that simple and put it independent of the other
if statement?
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 749778e..f4a7fd4 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -458,6 +458,14 @@ static int save_user_regs(struct pt_regs *regs, struct mcon
return 1;
msr |= MSR_VSX;
}
+ /*
+ * With a small context structure we can't hold the VSX registers,
+ * hence clear the MSR value to indicate the state was not saved.
+ */
+ if (!ctx_has_vsx_region)
+ msr &= ~MSR_VSX;
+
+
#endif /* CONFIG_VSX */
#ifdef CONFIG_SPE
/* save spe registers */
^ permalink raw reply related
* Re: [PATCH 2/2] powerpc: mm: change pgtable index size for 64K page
From: Benjamin Herrenschmidt @ 2013-11-21 23:46 UTC (permalink / raw)
To: Liu Ping Fan; +Cc: Paul Mackerras, linuxppc-dev
In-Reply-To: <20131121221150.GB26359@iris.ozlabs.ibm.com>
On Fri, 2013-11-22 at 09:11 +1100, Paul Mackerras wrote:
> On Thu, Nov 21, 2013 at 10:17:55AM +0800, Liu Ping Fan wrote:
> > For 64K page, we waste half of the pte_t page. With this patch, after
> > changing PGD_INDEX_SIZE from 12 to 11, PTE_INDEX_SIZE from 8 to 9,
> > we can improve the usage of pte_t page and shrink the continuous phys
> > size for pgd_t.
Also you did you miss that we use the second half to store the
per-subpage hash info when using 64k on top of HW 4k ?
Cheers,
Ben.
> > Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> > ---
> > arch/powerpc/include/asm/pgtable-ppc64-64k.h | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
> > index a56b82f..f6955ff 100644
> > --- a/arch/powerpc/include/asm/pgtable-ppc64-64k.h
> > +++ b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
> > @@ -4,10 +4,10 @@
> > #include <asm-generic/pgtable-nopud.h>
> >
> >
> > -#define PTE_INDEX_SIZE 8
> > +#define PTE_INDEX_SIZE 9
> > #define PMD_INDEX_SIZE 10
> > #define PUD_INDEX_SIZE 0
> > -#define PGD_INDEX_SIZE 12
> > +#define PGD_INDEX_SIZE 11
>
> Nack. Those definitions are the way they are in order to have the PMD
> map 16MB, which is our large page size, so that transparent huge pages
> work.
>
> Paul.
^ permalink raw reply
* [PATCH] powerpc/booke: Only check for hugetlb in flush if vma != NULL
From: Scott Wood @ 2013-11-22 0:26 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Scott Wood
And in flush_hugetlb_page(), don't check whether vma is NULL after
we've already dereferenced it.
This was found by Dan using static analysis as described here:
https://lists.ozlabs.org/pipermail/linuxppc-dev/2013-November/113161.html
We currently get away with this because the callers that currently pass
NULL for vma seem to be 32-bit-only (e.g. highmem, and
CONFIG_DEBUG_PGALLOC in pgtable_32.c) Hugetlb is currently 64-bit only,
so we never saw a NULL vma here.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
---
arch/powerpc/mm/hugetlbpage-book3e.c | 3 +--
arch/powerpc/mm/tlb_nohash.c | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c
index 3bc7006..74551b5 100644
--- a/arch/powerpc/mm/hugetlbpage-book3e.c
+++ b/arch/powerpc/mm/hugetlbpage-book3e.c
@@ -117,6 +117,5 @@ void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
struct hstate *hstate = hstate_file(vma->vm_file);
unsigned long tsize = huge_page_shift(hstate) - 10;
- __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, tsize, 0);
-
+ __flush_tlb_page(vma->vm_mm, vmaddr, tsize, 0);
}
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index 41cd68d..358d743 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -305,7 +305,7 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
{
#ifdef CONFIG_HUGETLB_PAGE
- if (is_vm_hugetlb_page(vma))
+ if (vma && is_vm_hugetlb_page(vma))
flush_hugetlb_page(vma, vmaddr);
#endif
--
1.8.1.2
^ permalink raw reply related
* Re: [PATCH] powerpc/signals: Mark VSX not saved with small contexts
From: Carlos O'Donell @ 2013-11-22 0:53 UTC (permalink / raw)
To: Michael Neuling; +Cc: Steve Best, linuxppc-dev, Haren Myneni
In-Reply-To: <8900.1385072483@ale.ozlabs.ibm.com>
On 11/21/2013 05:21 PM, Michael Neuling wrote:
>>> What about the 64-bit code? I don't know the code but it appears at a glance to
>>> have the same bug.
>>
>> It doesn't happen with 64-bit code because there the context contains
>> a sigcontext which on ppc64 has vmx_reserve to store the entire VMX
>> state. Therefore 64-bit ppc always has space to store the VMX registers
>> in a userspace context switch. It is only the 32-bit ppc ABI that lacks
>> the space.
>
> VMX? I don't understand this at all. We extended the ucontext to
> handle the extra VSX state, so older code may still be using the small
> ucontext and we already have a bunch of checks in the 64bit case for
> this.
>
> I agree with Michael, we should add this to the 64 bit case. If we
> can't put VSX state in, then clear MSR VSX.
Sorry, typo, VSX not VMX.
I had not gone through the historical implementation of the 64-bit
code, I assumed it started with a sufficiently sized context structure,
but on closer review it didn't.
The addition of the *context functions in glibc for 64-bit power
happened in 2003 by glibc commit 609b4783, with the mcontext_t
being expanded to include
I see that the 64-bit userspace context was extended in 2008 by your
kernel commit ce48b210.
Thus you're right the check is needed in the 64-bit case.
However, at present the issue doesn't seem to trigger in the
64-bit userspace. Which is odd now that I review the code and
see that the 64-bit userspace context is smaller than the kernel
context (lacks the `+32' to the vmx_reserve space). It could just
be that the compiler finds no chance to use VSX and therefore
the existing test cases don't trigger the bug. I don't plan to
investigate this further given that we're going to fix the 64-bit case
also.
> So how about we make it that simple and put it independent of the other
> if statement?
>
> diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
> index 749778e..f4a7fd4 100644
> --- a/arch/powerpc/kernel/signal_32.c
> +++ b/arch/powerpc/kernel/signal_32.c
> @@ -458,6 +458,14 @@ static int save_user_regs(struct pt_regs *regs, struct mcon
> return 1;
> msr |= MSR_VSX;
> }
> + /*
> + * With a small context structure we can't hold the VSX registers,
> + * hence clear the MSR value to indicate the state was not saved.
> + */
> + if (!ctx_has_vsx_region)
> + msr &= ~MSR_VSX;
> +
> +
> #endif /* CONFIG_VSX */
> #ifdef CONFIG_SPE
> /* save spe registers */
>
Looks good to me, along with a similar fix for signal_64.c.
Cheers,
Carlos.
^ permalink raw reply
* Re: [PATCH] powerpc/signals: Mark VSX not saved with small contexts
From: Carlos O'Donell @ 2013-11-22 0:56 UTC (permalink / raw)
To: Michael Neuling; +Cc: Steve Best, linuxppc-dev, Haren Myneni
In-Reply-To: <528EAAEE.8070300@redhat.com>
On 11/21/2013 07:53 PM, Carlos O'Donell wrote:
> The addition of the *context functions in glibc for 64-bit power
> happened in 2003 by glibc commit 609b4783, with the mcontext_t
> being expanded to include
... support for VMX state via `long vmx_reserve[NVRREG+NVRREG+1];'.
Cheers,
Carlos.
^ permalink raw reply
* Re: [PATCH v2] panic: Make panic_timeout configurable
From: Michael Ellerman @ 2013-11-22 1:54 UTC (permalink / raw)
To: Jason Baron
Cc: Felipe Contreras, linux-kernel@vger.kernel.org,
ralf@linux-mips.org, paulus@samba.org, Andrew Morton,
linuxppc-dev@lists.ozlabs.org, Ingo Molnar
In-Reply-To: <528E795A.6070600@akamai.com>
On Thu, Nov 21, 2013 at 04:21:30PM -0500, Jason Baron wrote:
> On 11/21/2013 06:16 AM, Michael Ellerman wrote:
> > On Tue, Nov 19, 2013 at 05:04:14PM -0500, Jason Baron wrote:
> >> On 11/19/2013 02:09 AM, Ingo Molnar wrote:
> >>>
> >>> * Jason Baron <jbaron@akamai.com> wrote:
> >>>
> >>>> On 11/18/2013 05:30 PM, Andrew Morton wrote:
> >>>>> On Mon, 18 Nov 2013 21:04:36 +0000 (GMT) Jason Baron <jbaron@akamai.com> wrote:
> >>>>>
> >>>>>> The panic_timeout value can be set via the command line option 'panic=x', or via
> >>>>>> /proc/sys/kernel/panic, however that is not sufficient when the panic occurs
> >>>>>> before we are able to set up these values. Thus, add a CONFIG_PANIC_TIMEOUT
> >>>>>> so that we can set the desired value from the .config.
> >>>>>>
> >>>>>> The default panic_timeout value continues to be 0 - wait forever,
> >>>>>> except for powerpc and mips, which have been defaulted to 180 and
> >>>>>> 5 respectively. This is in keeping with the fact that these
> >>>>>> arches already set panic_timeout in their arch init code.
> >>>>>> However, I found three exceptions- two in mips and one in powerpc
> >>>>>> where the settings didn't match these default values. In those
> >>>>>> cases, I left the arch code so it continues to override, in case
> >>>>>> the user has not changed from the default. It would nice if these
> >>>>>> arches had one default value, or if we could determine the
> >>>>>> correct setting at compile-time.
> > ...
> >>
> >> Sure, I can round up all the related patches in this area that make
> >> sense and re-submit as a series.
> >>
> >> Felipe, would the CONFIG_PANIC_TIMEOUT=xx .config parameter work for your
> >> needs, or would you still like to see the command-line processing moved
> >> up?
> >>
> >> I'd also like to hear from the PowerPC folks about the arch defaults
> >> there. Now, that mips is ok with CONFIG_PANIC_TIMEOUT, PowerPC is the
> >> only arch doing specific initialization of 'panic_timeout'.
> >
> > Hi Jason,
> >
> > I think we'd like to choose the value at runtime, as we do now. The
> > powerpc arch supports a wide spread of different hardware, so it's nice
> > to be able to customise the value based on the platform. Also we build a
> > single kernel that boots on many platforms, and so we can't pick the
> > value at compile time.
>
> Hi,
>
> Ok, So powerpc sets the timeout to '180' during setup_arch(), but then
> overrides the value to '10' only for pSeries.
Yep.
> The patch proposed in this thread, sets the default built-in value for
> powerpc to 180 and then continues to override in pSeries, if its
> still 180 (IE the user hasn't requested another value). This allows
> the panic_timeout value to have an effect before we reach the
> arch_init() code. Are you ok with this? That is, are you ok with the
> proposed powerpc bits?
Yes that looks OK to me.
It means we get a non-zero value during early boot, which is nice, the
user can override the value if they wish, and otherwise the existing
behaviour is unchanged.
cheers
^ permalink raw reply
* Re: [PATCH 2/2] powerpc: mm: change pgtable index size for 64K page
From: Michael Ellerman @ 2013-11-22 2:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Paul Mackerras, Liu Ping Fan
In-Reply-To: <1385077581.4882.30.camel@pasglop>
On Fri, 2013-11-22 at 10:46 +1100, Benjamin Herrenschmidt wrote:
> On Fri, 2013-11-22 at 09:11 +1100, Paul Mackerras wrote:
> > On Thu, Nov 21, 2013 at 10:17:55AM +0800, Liu Ping Fan wrote:
> > > For 64K page, we waste half of the pte_t page. With this patch, after
> > > changing PGD_INDEX_SIZE from 12 to 11, PTE_INDEX_SIZE from 8 to 9,
> > > we can improve the usage of pte_t page and shrink the continuous phys
> > > size for pgd_t.
>
> Also you did you miss that we use the second half to store the
> per-subpage hash info when using 64k on top of HW 4k ?
Given the subtleties perhaps a nice big block comment is in order ? :)
cheers
^ permalink raw reply
* [PATCH 0/8] IBM Akebono/PPC476GTR Support
From: Alistair Popple @ 2013-11-22 2:07 UTC (permalink / raw)
To: benh
Cc: netdev, linux-usb, linux-mmc, linuxppc-dev, stern,
Alistair Popple, cjb, davem
The IBM Akebono board is a development board for the new PPC476GTR
system on chip (SoC).
Changes from V1:
* Update device-tree compatible strings to reflect the name of the
SoC rather than the board when those components are integrated into
the SoC.
* Updates to allow the new EMAC PHY interface to be compile tested.
* Rather than adding a new compatible string for EHCI support
usb-ehci is used and the corresponding driver (ehci-ppc-of)
is merged into the generic EHCI platform driver.
* A generic (usb-ohci) compatible string is used for OHCI.
* PCI MSI support has been added via the HSTA module.
Alistair Popple (8):
IBM Akebono: Add support to AHCI platform driver
IBM Akebono: Add a SDHCI platform driver
IBM Akebono: Add support for a new PHY interface to the IBM emac
driver
IBM Akebono: Add support to the OHCI platform driver for PPC476GTR
ECHI Platform: Merge ppc-of EHCI driver into the ehci-platform driver
IBM Currituck: Clean up board specific code before adding Akebono
code
IBM Akebono: Add the Akebono platform
powerpc: Added PCI MSI support using the HSTA module
.../devicetree/bindings/powerpc/4xx/akebono.txt | 54 +++
.../devicetree/bindings/powerpc/4xx/emac.txt | 9 +
arch/powerpc/boot/Makefile | 3 +
arch/powerpc/boot/dcr.h | 4 +
arch/powerpc/boot/dts/akebono.dts | 415 ++++++++++++++++++++
arch/powerpc/boot/treeboot-akebono.c | 179 +++++++++
arch/powerpc/boot/wrapper | 3 +
arch/powerpc/configs/44x/akebono_defconfig | 148 +++++++
arch/powerpc/platforms/44x/Kconfig | 32 +-
arch/powerpc/platforms/44x/Makefile | 3 +-
arch/powerpc/platforms/44x/currituck.c | 233 -----------
arch/powerpc/platforms/44x/ppc476.c | 299 ++++++++++++++
arch/powerpc/sysdev/Kconfig | 6 +
arch/powerpc/sysdev/Makefile | 1 +
arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 266 +++++++++++++
arch/powerpc/sysdev/ppc4xx_pci.c | 41 +-
arch/powerpc/sysdev/ppc4xx_pci.h | 4 +-
drivers/ata/ahci_platform.c | 1 +
drivers/mmc/host/Kconfig | 12 +
drivers/mmc/host/Makefile | 1 +
drivers/mmc/host/sdhci-of-476gtr.c | 60 +++
drivers/net/ethernet/ibm/emac/Kconfig | 4 +
drivers/net/ethernet/ibm/emac/Makefile | 1 +
drivers/net/ethernet/ibm/emac/core.c | 50 ++-
drivers/net/ethernet/ibm/emac/core.h | 12 +
drivers/net/ethernet/ibm/emac/rgmii_wol.c | 243 ++++++++++++
drivers/net/ethernet/ibm/emac/rgmii_wol.h | 62 +++
drivers/usb/host/Kconfig | 7 +-
drivers/usb/host/ehci-hcd.c | 5 -
drivers/usb/host/ehci-platform.c | 86 +++-
drivers/usb/host/ehci-ppc-of.c | 236 -----------
drivers/usb/host/ohci-platform.c | 22 +-
32 files changed, 1992 insertions(+), 510 deletions(-)
create mode 100644 Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
create mode 100644 arch/powerpc/boot/dts/akebono.dts
create mode 100644 arch/powerpc/boot/treeboot-akebono.c
create mode 100644 arch/powerpc/configs/44x/akebono_defconfig
delete mode 100644 arch/powerpc/platforms/44x/currituck.c
create mode 100644 arch/powerpc/platforms/44x/ppc476.c
create mode 100644 arch/powerpc/sysdev/ppc4xx_hsta_msi.c
create mode 100644 drivers/mmc/host/sdhci-of-476gtr.c
create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.c
create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.h
delete mode 100644 drivers/usb/host/ehci-ppc-of.c
--
1.7.10.4
^ permalink raw reply
* [PATCH 1/8] IBM Akebono: Add support to AHCI platform driver
From: Alistair Popple @ 2013-11-22 2:08 UTC (permalink / raw)
To: benh; +Cc: linux-ide, linuxppc-dev, Alistair Popple
In-Reply-To: <1385086057-10884-1-git-send-email-alistair@popple.id.au>
The new IBM Akebono board has a PPC476GTR SoC with an AHCI compliant
SATA controller. This patch adds a compatible property for the new SoC
to the AHCI platform driver.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Cc: linux-ide@vger.kernel.org
---
drivers/ata/ahci_platform.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 7d3b853..e247594 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -328,6 +328,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
static const struct of_device_id ahci_of_match[] = {
{ .compatible = "snps,spear-ahci", },
{ .compatible = "snps,exynos5440-ahci", },
+ { .compatible = "ibm,476gtr-ahci", },
{},
};
MODULE_DEVICE_TABLE(of, ahci_of_match);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/8] IBM Akebono: Add a SDHCI platform driver
From: Alistair Popple @ 2013-11-22 2:08 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, Chris Ball, linux-mmc, Alistair Popple
In-Reply-To: <1385086057-10884-1-git-send-email-alistair@popple.id.au>
This patch adds a SDHCI platform driver for the new IBM PPC476GTR SoC
which is on the Akebono board.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Cc: Chris Ball <cjb@laptop.org>
Cc: linux-mmc@vger.kernel.org
---
drivers/mmc/host/Kconfig | 12 ++++++++
drivers/mmc/host/Makefile | 1 +
drivers/mmc/host/sdhci-of-476gtr.c | 60 ++++++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+)
create mode 100644 drivers/mmc/host/sdhci-of-476gtr.c
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 7fc5099..14210df 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -130,6 +130,18 @@ config MMC_SDHCI_OF_HLWD
If unsure, say N.
+config MMC_SDHCI_OF_476GTR
+ tristate "SDHCI OF support for the IBM PPC476GTR SoC"
+ depends on MMC_SDHCI_PLTFM
+ depends on PPC_OF
+ help
+ This selects the Secure Digital Host Controller Interface (SDHCI)
+ found on the PPC476GTR SoC.
+
+ If you have a controller with this interface, say Y or M here.
+
+ If unsure, say N.
+
config MMC_SDHCI_CNS3XXX
tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
depends on ARCH_CNS3XXX
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index c41d0c3..92beff3 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_MMC_SDHCI_DOVE) += sdhci-dove.o
obj-$(CONFIG_MMC_SDHCI_TEGRA) += sdhci-tegra.o
obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o
obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o
+obj-$(CONFIG_MMC_SDHCI_OF_476GTR) += sdhci-of-476gtr.o
obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o
obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o
diff --git a/drivers/mmc/host/sdhci-of-476gtr.c b/drivers/mmc/host/sdhci-of-476gtr.c
new file mode 100644
index 0000000..1310f8c
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of-476gtr.c
@@ -0,0 +1,60 @@
+/*
+ * drivers/mmc/host/sdhci-of-476gtr.c
+ *
+ * Copyright © 2013 Alistair Popple <alistair@popple.id.au> IBM Corporation
+ *
+ * Based on sdhci-of-hlwd.c
+ *
+ * Copyright (C) 2009 The GameCube Linux Team
+ * Copyright (C) 2009 Albert Herranz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mmc/host.h>
+#include "sdhci-pltfm.h"
+
+static const struct sdhci_ops sdhci_476gtr_ops = {
+};
+
+static const struct sdhci_pltfm_data sdhci_476gtr_pdata = {
+ .ops = &sdhci_476gtr_ops,
+};
+
+static int sdhci_476gtr_probe(struct platform_device *pdev)
+{
+ return sdhci_pltfm_register(pdev, &sdhci_476gtr_pdata, 0);
+}
+
+static int sdhci_476gtr_remove(struct platform_device *pdev)
+{
+ return sdhci_pltfm_unregister(pdev);
+}
+
+static const struct of_device_id sdhci_476gtr_of_match[] = {
+ { .compatible = "ibm,476gtr-sdhci" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sdhci_476gtr_of_match);
+
+static struct platform_driver sdhci_476gtr_driver = {
+ .driver = {
+ .name = "sdhci-476gtr",
+ .owner = THIS_MODULE,
+ .of_match_table = sdhci_476gtr_of_match,
+ .pm = SDHCI_PLTFM_PMOPS,
+ },
+ .probe = sdhci_476gtr_probe,
+ .remove = sdhci_476gtr_remove,
+};
+
+module_platform_driver(sdhci_476gtr_driver);
+
+MODULE_DESCRIPTION("PPC476GTR SDHCI OF driver");
+MODULE_AUTHOR("Alistair Popple");
+MODULE_LICENSE("GPL v2");
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/8] IBM Akebono: Add support for a new PHY interface to the IBM emac driver
From: Alistair Popple @ 2013-11-22 2:08 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, netdev, David S. Miller, Alistair Popple
In-Reply-To: <1385086057-10884-1-git-send-email-alistair@popple.id.au>
The IBM PPC476GTR SoC that is used on the Akebono board uses a
different ethernet PHY interface that has wake on lan (WOL) support
with the IBM emac. This patch adds support to the IBM emac driver for
this new PHY interface.
At this stage the wake on lan functionality has not been implemented.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
---
.../devicetree/bindings/powerpc/4xx/emac.txt | 9 +
drivers/net/ethernet/ibm/emac/Kconfig | 4 +
drivers/net/ethernet/ibm/emac/Makefile | 1 +
drivers/net/ethernet/ibm/emac/core.c | 50 +++-
drivers/net/ethernet/ibm/emac/core.h | 12 +
drivers/net/ethernet/ibm/emac/rgmii_wol.c | 243 ++++++++++++++++++++
drivers/net/ethernet/ibm/emac/rgmii_wol.h | 62 +++++
7 files changed, 375 insertions(+), 6 deletions(-)
create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.c
create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.h
diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
index 712baf6..9928d9d 100644
--- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
+++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
@@ -61,6 +61,8 @@
Fox Axon: present, whatever value is appropriate for each
EMAC, that is the content of the current (bogus) "phy-port"
property.
+ - rgmii-wol-device : 1 cell, required iff conntect to a RGMII in the WKUP
+ power domain. phandle of the RGMII-WOL device node.
Optional properties:
- phy-address : 1 cell, optional, MDIO address of the PHY. If absent,
@@ -146,3 +148,10 @@
available.
For Axon: 0x0000012a
+ iv) RGMII-WOL node
+
+ Required properties:
+ - compatible : compatible list, containing 2 entries, first is
+ "ibm,rgmii-wol-CHIP" where CHIP is the host ASIC (like
+ EMAC) and the second is "ibm,rgmii-wol".
+ - reg : <registers mapping>
diff --git a/drivers/net/ethernet/ibm/emac/Kconfig b/drivers/net/ethernet/ibm/emac/Kconfig
index 3f44a30..56ea346 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -55,6 +55,10 @@ config IBM_EMAC_RGMII
bool
default n
+config IBM_EMAC_RGMII_WOL
+ bool "IBM EMAC RGMII wake-on-LAN support" if COMPILE_TEST
+ default n
+
config IBM_EMAC_TAH
bool
default n
diff --git a/drivers/net/ethernet/ibm/emac/Makefile b/drivers/net/ethernet/ibm/emac/Makefile
index eba2183..8843803 100644
--- a/drivers/net/ethernet/ibm/emac/Makefile
+++ b/drivers/net/ethernet/ibm/emac/Makefile
@@ -7,5 +7,6 @@ obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
ibm_emac-y := mal.o core.o phy.o
ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += zmii.o
ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += rgmii.o
+ibm_emac-$(CONFIG_IBM_EMAC_RGMII_WOL) += rgmii_wol.o
ibm_emac-$(CONFIG_IBM_EMAC_TAH) += tah.o
ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += debug.o
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index 6b5c722..fc1a775 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -630,6 +630,8 @@ static int emac_configure(struct emac_instance *dev)
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_set_speed(dev->rgmii_dev, dev->rgmii_port,
dev->phy.speed);
+ if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+ rgmii_wol_set_speed(dev->rgmii_wol_dev, dev->phy.speed);
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
zmii_set_speed(dev->zmii_dev, dev->zmii_port, dev->phy.speed);
@@ -797,6 +799,8 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg)
zmii_get_mdio(dev->zmii_dev, dev->zmii_port);
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port);
+ if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+ rgmii_wol_get_mdio(dev->rgmii_wol_dev);
/* Wait for management interface to become idle */
n = 20;
@@ -844,6 +848,8 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg)
DBG2(dev, "mdio_read -> %04x" NL, r);
err = 0;
bail:
+ if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+ rgmii_wol_put_mdio(dev->rgmii_wol_dev);
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_put_mdio(dev->rgmii_dev, dev->rgmii_port);
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
@@ -869,6 +875,8 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg,
zmii_get_mdio(dev->zmii_dev, dev->zmii_port);
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port);
+ if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+ rgmii_wol_get_mdio(dev->rgmii_wol_dev);
/* Wait for management interface to be idle */
n = 20;
@@ -907,6 +915,8 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg,
}
err = 0;
bail:
+ if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+ rgmii_wol_put_mdio(dev->rgmii_wol_dev);
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_put_mdio(dev->rgmii_dev, dev->rgmii_port);
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
@@ -2275,10 +2285,11 @@ struct emac_depentry {
#define EMAC_DEP_MAL_IDX 0
#define EMAC_DEP_ZMII_IDX 1
#define EMAC_DEP_RGMII_IDX 2
-#define EMAC_DEP_TAH_IDX 3
-#define EMAC_DEP_MDIO_IDX 4
-#define EMAC_DEP_PREV_IDX 5
-#define EMAC_DEP_COUNT 6
+#define EMAC_DEP_RGMII_WOL_IDX 3
+#define EMAC_DEP_TAH_IDX 4
+#define EMAC_DEP_MDIO_IDX 5
+#define EMAC_DEP_PREV_IDX 6
+#define EMAC_DEP_COUNT 7
static int emac_check_deps(struct emac_instance *dev,
struct emac_depentry *deps)
@@ -2356,6 +2367,7 @@ static int emac_wait_deps(struct emac_instance *dev)
deps[EMAC_DEP_MAL_IDX].phandle = dev->mal_ph;
deps[EMAC_DEP_ZMII_IDX].phandle = dev->zmii_ph;
deps[EMAC_DEP_RGMII_IDX].phandle = dev->rgmii_ph;
+ deps[EMAC_DEP_RGMII_WOL_IDX].phandle = dev->rgmii_wol_ph;
if (dev->tah_ph)
deps[EMAC_DEP_TAH_IDX].phandle = dev->tah_ph;
if (dev->mdio_ph)
@@ -2378,6 +2390,7 @@ static int emac_wait_deps(struct emac_instance *dev)
dev->mal_dev = deps[EMAC_DEP_MAL_IDX].ofdev;
dev->zmii_dev = deps[EMAC_DEP_ZMII_IDX].ofdev;
dev->rgmii_dev = deps[EMAC_DEP_RGMII_IDX].ofdev;
+ dev->rgmii_wol_dev = deps[EMAC_DEP_RGMII_WOL_IDX].ofdev;
dev->tah_dev = deps[EMAC_DEP_TAH_IDX].ofdev;
dev->mdio_dev = deps[EMAC_DEP_MDIO_IDX].ofdev;
}
@@ -2583,6 +2596,8 @@ static int emac_init_config(struct emac_instance *dev)
dev->rgmii_ph = 0;
if (emac_read_uint_prop(np, "rgmii-channel", &dev->rgmii_port, 0))
dev->rgmii_port = 0xffffffff;
+ if (emac_read_uint_prop(np, "rgmii-wol-device", &dev->rgmii_wol_ph, 0))
+ dev->rgmii_wol_ph = 0;
if (emac_read_uint_prop(np, "fifo-entry-size", &dev->fifo_entry_size, 0))
dev->fifo_entry_size = 16;
if (emac_read_uint_prop(np, "mal-burst-size", &dev->mal_burst_size, 0))
@@ -2669,6 +2684,16 @@ static int emac_init_config(struct emac_instance *dev)
#endif
}
+ if (dev->rgmii_wol_ph != 0) {
+#ifdef CONFIG_IBM_EMAC_RGMII_WOL
+ dev->features |= EMAC_FTR_HAS_RGMII_WOL;
+#else
+ printk(KERN_ERR "%s: RGMII WOL support not enabled !\n",
+ np->full_name);
+ return -ENXIO;
+#endif
+ }
+
/* Read MAC-address */
p = of_get_property(np, "local-mac-address", NULL);
if (p == NULL) {
@@ -2842,10 +2867,15 @@ static int emac_probe(struct platform_device *ofdev)
(err = rgmii_attach(dev->rgmii_dev, dev->rgmii_port, dev->phy_mode)) != 0)
goto err_detach_zmii;
+ /* Attach to RGMII_WOL, if needed */
+ if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL) &&
+ (err = rgmii_wol_attach(dev->rgmii_wol_dev, dev->phy_mode)) != 0)
+ goto err_detach_rgmii;
+
/* Attach to TAH, if needed */
if (emac_has_feature(dev, EMAC_FTR_HAS_TAH) &&
(err = tah_attach(dev->tah_dev, dev->tah_port)) != 0)
- goto err_detach_rgmii;
+ goto err_detach_rgmii_wol;
/* Set some link defaults before we can find out real parameters */
dev->phy.speed = SPEED_100;
@@ -2918,6 +2948,9 @@ static int emac_probe(struct platform_device *ofdev)
err_detach_tah:
if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
tah_detach(dev->tah_dev, dev->tah_port);
+ err_detach_rgmii_wol:
+ if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+ rgmii_wol_detach(dev->rgmii_wol_dev);
err_detach_rgmii:
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_detach(dev->rgmii_dev, dev->rgmii_port);
@@ -3079,12 +3112,17 @@ static int __init emac_init(void)
rc = tah_init();
if (rc)
goto err_rgmii;
- rc = platform_driver_register(&emac_driver);
+ rc = rgmii_wol_init();
if (rc)
goto err_tah;
+ rc = platform_driver_register(&emac_driver);
+ if (rc)
+ goto err_rgmii_wol;
return 0;
+ err_rgmii_wol:
+ rgmii_wol_exit();
err_tah:
tah_exit();
err_rgmii:
diff --git a/drivers/net/ethernet/ibm/emac/core.h b/drivers/net/ethernet/ibm/emac/core.h
index 7007479..930a6f6 100644
--- a/drivers/net/ethernet/ibm/emac/core.h
+++ b/drivers/net/ethernet/ibm/emac/core.h
@@ -43,6 +43,7 @@
#include "phy.h"
#include "zmii.h"
#include "rgmii.h"
+#include "rgmii_wol.h"
#include "mal.h"
#include "tah.h"
#include "debug.h"
@@ -210,6 +211,10 @@ struct emac_instance {
u32 rgmii_port;
struct platform_device *rgmii_dev;
+ /* RGMII WOL infos if any */
+ u32 rgmii_wol_ph;
+ struct platform_device *rgmii_wol_dev;
+
/* TAH infos if any */
u32 tah_ph;
u32 tah_port;
@@ -333,6 +338,10 @@ struct emac_instance {
* APM821xx does not support Half Duplex mode
*/
#define EMAC_FTR_APM821XX_NO_HALF_DUPLEX 0x00001000
+/*
+ * Set if we have a RGMII with wake on LAN.
+ */
+#define EMAC_FTR_HAS_RGMII_WOL 0x00020000
/* Right now, we don't quite handle the always/possible masks on the
* most optimal way as we don't have a way to say something like
@@ -356,6 +365,9 @@ enum {
#ifdef CONFIG_IBM_EMAC_RGMII
EMAC_FTR_HAS_RGMII |
#endif
+#ifdef CONFIG_IBM_EMAC_RGMII_WOL
+ EMAC_FTR_HAS_RGMII_WOL |
+#endif
#ifdef CONFIG_IBM_EMAC_NO_FLOW_CTRL
EMAC_FTR_NO_FLOW_CONTROL_40x |
#endif
diff --git a/drivers/net/ethernet/ibm/emac/rgmii_wol.c b/drivers/net/ethernet/ibm/emac/rgmii_wol.c
new file mode 100644
index 0000000..aeeb5dd
--- /dev/null
+++ b/drivers/net/ethernet/ibm/emac/rgmii_wol.c
@@ -0,0 +1,243 @@
+/* drivers/net/ethernet/ibm/emac/rgmii_wol.c
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge with
+ * wake on LAN support.
+ *
+ * Copyright 2013 Alistair Popple, IBM Corp.
+ * <alistair@popple.id.au>
+ *
+ * Based on rgmii.h:
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/ethtool.h>
+#include <linux/io.h>
+
+#include "emac.h"
+#include "debug.h"
+
+/* RGMII_WOL_REG */
+
+#define WKUP_ETH_RGSPD 0xC0000000
+#define WKUP_ETH_FCSEN 0x20000000
+#define WKUP_ETH_CRSEN 0x02000000
+#define WKUP_ETH_COLEN 0x01000000
+#define WKUP_ETH_TX_OE 0x00040000
+#define WKUP_ETH_RX_IE 0x00020000
+#define WKUP_ETH_RGMIIEN 0x00010000
+
+#define WKUP_ETH_RGSPD_10 0x00000000
+#define WKUP_ETH_RGSPD_100 0x40000000
+#define WKUP_ETH_RGSPD_1000 0x80000000
+
+/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
+static inline int rgmii_valid_mode(int phy_mode)
+{
+ return phy_mode == PHY_MODE_GMII ||
+ phy_mode == PHY_MODE_MII ||
+ phy_mode == PHY_MODE_RGMII ||
+ phy_mode == PHY_MODE_TBI ||
+ phy_mode == PHY_MODE_RTBI;
+}
+
+int rgmii_wol_attach(struct platform_device *ofdev, int mode)
+{
+ struct rgmii_wol_instance *dev = platform_get_drvdata(ofdev);
+
+ dev_dbg(&ofdev->dev, "attach\n");
+
+ /* Check if we need to attach to a RGMII */
+ if (!rgmii_valid_mode(mode)) {
+ dev_err(&ofdev->dev, "unsupported settings !\n");
+ return -ENODEV;
+ }
+
+ mutex_lock(&dev->lock);
+
+ /* Enable this input */
+ out_be32(dev->reg, in_be32(dev->reg) | WKUP_ETH_RGMIIEN
+ | WKUP_ETH_TX_OE | WKUP_ETH_RX_IE);
+
+ ++dev->users;
+
+ mutex_unlock(&dev->lock);
+
+ return 0;
+}
+
+void rgmii_wol_set_speed(struct platform_device *ofdev, int speed)
+{
+ struct rgmii_wol_instance *dev = platform_get_drvdata(ofdev);
+ u32 reg;
+
+ mutex_lock(&dev->lock);
+
+ reg = in_be32(dev->reg) & ~WKUP_ETH_RGSPD;
+
+ dev_dbg(&ofdev->dev, "speed(%d)\n", speed);
+
+ switch (speed) {
+ case SPEED_1000:
+ reg |= WKUP_ETH_RGSPD_1000;
+ break;
+ case SPEED_100:
+ reg |= WKUP_ETH_RGSPD_100;
+ break;
+ case SPEED_10:
+ reg |= WKUP_ETH_RGSPD_10;
+ break;
+ default:
+ dev_err(&ofdev->dev, "invalid speed set!\n");
+ }
+
+ out_be32(dev->reg, reg);
+
+ mutex_unlock(&dev->lock);
+}
+
+void rgmii_wol_get_mdio(struct platform_device *ofdev)
+{
+ /* MDIO is always enabled when RGMII_WOL is enabled, so we
+ * don't have to do anything here.
+ */
+ dev_dbg(&ofdev->dev, "get_mdio\n");
+}
+
+void rgmii_wol_put_mdio(struct platform_device *ofdev)
+{
+ dev_dbg(&ofdev->dev, "put_mdio\n");
+}
+
+void rgmii_wol_detach(struct platform_device *ofdev)
+{
+ struct rgmii_wol_instance *dev = platform_get_drvdata(ofdev);
+
+ BUG_ON(!dev || dev->users == 0);
+
+ mutex_lock(&dev->lock);
+
+ dev_dbg(&ofdev->dev, "detach\n");
+
+ /* Disable this input */
+ out_be32(dev->reg, 0);
+
+ --dev->users;
+
+ mutex_unlock(&dev->lock);
+}
+
+int rgmii_wol_get_regs_len(struct platform_device *ofdev)
+{
+ return sizeof(struct emac_ethtool_regs_subhdr) +
+ sizeof(u32);
+}
+
+void *rgmii_wol_dump_regs(struct platform_device *ofdev, void *buf)
+{
+ struct rgmii_wol_instance *dev = platform_get_drvdata(ofdev);
+ struct emac_ethtool_regs_subhdr *hdr = buf;
+ u32 *regs = (u32 *)(hdr + 1);
+
+ hdr->version = 0;
+ hdr->index = 0; /* for now, are there chips with more than one
+ * rgmii ? if yes, then we'll add a cell_index
+ * like we do for emac
+ */
+ memcpy_fromio(regs, dev->reg, sizeof(u32));
+ return regs + 1;
+}
+
+
+static int rgmii_wol_probe(struct platform_device *ofdev)
+{
+ struct device_node *np = ofdev->dev.of_node;
+ struct rgmii_wol_instance *dev;
+ int rc;
+
+ rc = -ENOMEM;
+ dev = kzalloc(sizeof(struct rgmii_wol_instance), GFP_KERNEL);
+ if (dev == NULL)
+ goto err_gone;
+
+ mutex_init(&dev->lock);
+
+ dev->reg = of_iomap(np, 0);
+ if (!dev->reg) {
+ dev_err(&ofdev->dev, "Can't map registers\n");
+ rc = -ENXIO;
+ goto err_free;
+ }
+
+ /* Check for RGMII flags */
+ if (of_get_property(ofdev->dev.of_node, "has-mdio", NULL))
+ dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
+
+ dev_dbg(&ofdev->dev, " Boot REG = 0x%08x\n", in_be32(dev->reg));
+
+ /* Disable all inputs by default */
+ out_be32(dev->reg, 0);
+
+ dev_info(&ofdev->dev,
+ "RGMII %s initialized with%s MDIO support\n",
+ ofdev->dev.of_node->full_name,
+ (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out");
+
+ wmb();
+ platform_set_drvdata(ofdev, dev);
+
+ return 0;
+
+ err_free:
+ kfree(dev);
+ err_gone:
+ return rc;
+}
+
+static int rgmii_wol_remove(struct platform_device *ofdev)
+{
+ struct rgmii_wol_instance *dev = platform_get_drvdata(ofdev);
+
+ WARN_ON(dev->users != 0);
+
+ iounmap(dev->reg);
+ kfree(dev);
+
+ return 0;
+}
+
+static struct of_device_id rgmii_wol_match[] = {
+ {
+ .compatible = "ibm,rgmii-wol",
+ },
+ {
+ .type = "emac-rgmii-wol",
+ },
+ {},
+};
+
+static struct platform_driver rgmii_wol_driver = {
+ .driver = {
+ .name = "emac-rgmii-wol",
+ .owner = THIS_MODULE,
+ .of_match_table = rgmii_wol_match,
+ },
+ .probe = rgmii_wol_probe,
+ .remove = rgmii_wol_remove,
+};
+
+int __init rgmii_wol_init(void)
+{
+ return platform_driver_register(&rgmii_wol_driver);
+}
+
+void rgmii_wol_exit(void)
+{
+ platform_driver_unregister(&rgmii_wol_driver);
+}
diff --git a/drivers/net/ethernet/ibm/emac/rgmii_wol.h b/drivers/net/ethernet/ibm/emac/rgmii_wol.h
new file mode 100644
index 0000000..9f0b589
--- /dev/null
+++ b/drivers/net/ethernet/ibm/emac/rgmii_wol.h
@@ -0,0 +1,62 @@
+/* drivers/net/ethernet/ibm/emac/rgmii_wol.h
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge with
+ * wake on LAN support.
+ *
+ * Copyright 2013 Alistair Popple, IBM Corp.
+ * <alistair@popple.id.au>
+ *
+ * Based on rgmii.h:
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __IBM_NEWEMAC_RGMII_WOL_H
+#define __IBM_NEWEMAC_RGMII_WOL_H
+
+/* RGMII device */
+struct rgmii_wol_instance {
+ u32 __iomem *reg;
+
+ /* RGMII bridge flags */
+ int flags;
+#define EMAC_RGMII_FLAG_HAS_MDIO 0x00000001
+
+ /* Only one EMAC whacks us at a time */
+ struct mutex lock;
+
+ /* number of EMACs using this RGMII bridge */
+ int users;
+};
+
+#ifdef CONFIG_IBM_EMAC_RGMII_WOL
+
+extern int rgmii_wol_init(void);
+extern void rgmii_wol_exit(void);
+extern int rgmii_wol_attach(struct platform_device *ofdev, int mode);
+extern void rgmii_wol_detach(struct platform_device *ofdev);
+extern void rgmii_wol_get_mdio(struct platform_device *ofdev);
+extern void rgmii_wol_put_mdio(struct platform_device *ofdev);
+extern void rgmii_wol_set_speed(struct platform_device *ofdev, int speed);
+extern int rgmii_wol_get_regs_len(struct platform_device *ofdev);
+extern void *rgmii_wol_dump_regs(struct platform_device *ofdev, void *buf);
+
+#else
+
+# define rgmii_wol_init() 0
+# define rgmii_wol_exit() do { } while (0)
+# define rgmii_wol_attach(x, y) (-ENXIO)
+# define rgmii_wol_detach(x) do { } while (0)
+# define rgmii_wol_get_mdio(o) do { } while (0)
+# define rgmii_wol_put_mdio(o) do { } while (0)
+# define rgmii_wol_set_speed(x, y) do { } while (0)
+# define rgmii_wol_get_regs_len(x) 0
+# define rgmii_wol_dump_regs(x, buf) (buf)
+#endif /* !CONFIG_IBM_EMAC_RGMII_WOL */
+
+#endif /* __IBM_NEWEMAC_RGMII_WOL_H */
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/8] IBM Akebono: Add support to the OHCI platform driver for PPC476GTR
From: Alistair Popple @ 2013-11-22 2:08 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, linux-usb, Alistair Popple
In-Reply-To: <1385086057-10884-1-git-send-email-alistair@popple.id.au>
The IBM Akebono board uses the PPC476GTR SoC which has a OHCI
compliant USB host interface. This patch adds support for it to the
OHCI platform driver.
As we use device tree to pass platform specific data instead of
platform data we remove the check for platform data and instead
provide reasonable defaults if no platform data is present. This is
similar to what is currently done in ehci-platform.c.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb@vger.kernel.org
---
drivers/usb/host/ohci-platform.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index a4c6410..e1ae5d3 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -23,6 +23,8 @@
#include <linux/usb/ohci_pdriver.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
+#include <linux/slab.h>
+#include <linux/of.h>
#include "ohci.h"
@@ -55,6 +57,8 @@ static const struct ohci_driver_overrides platform_overrides __initconst = {
.reset = ohci_platform_reset,
};
+static struct usb_ohci_pdata ohci_platform_defaults;
+
static int ohci_platform_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
@@ -63,14 +67,16 @@ static int ohci_platform_probe(struct platform_device *dev)
int irq;
int err = -ENOMEM;
- if (!pdata) {
- WARN_ON(1);
- return -ENODEV;
- }
-
if (usb_disabled())
return -ENODEV;
+ /*
+ * Platforms using DT don't always provide platform data.
+ * This should provide reasonable defaults.
+ */
+ if (!pdata)
+ dev->dev.platform_data = pdata = &ohci_platform_defaults;
+
irq = platform_get_irq(dev, 0);
if (irq < 0) {
dev_err(&dev->dev, "no irq provided");
@@ -171,6 +177,11 @@ static int ohci_platform_resume(struct device *dev)
#define ohci_platform_resume NULL
#endif /* CONFIG_PM */
+static const struct of_device_id ohci_of_match[] = {
+ { .compatible = "usb-ohci", },
+ {},
+};
+
static const struct platform_device_id ohci_platform_table[] = {
{ "ohci-platform", 0 },
{ }
@@ -191,6 +202,7 @@ static struct platform_driver ohci_platform_driver = {
.owner = THIS_MODULE,
.name = "ohci-platform",
.pm = &ohci_platform_pm_ops,
+ .of_match_table = ohci_of_match,
}
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 5/8] ECHI Platform: Merge ppc-of EHCI driver into the ehci-platform driver
From: Alistair Popple @ 2013-11-22 2:08 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, Alistair Popple
In-Reply-To: <1385086057-10884-1-git-send-email-alistair@popple.id.au>
Currently the ppc-of driver uses the compatibility string
"usb-ehci". This means platforms that use device-tree and implement an
EHCI compatible interface have to either use the ppc-of driver or add
a compatible line to the ehci-platform driver. It would be more
appropriate for the platform driver to be compatible with "usb-ehci"
as non-powerpc platforms are also beginning to utilise device-tree.
This patch merges the device tree property parsing from ehci-ppc-of
into the platform driver and adds a "usb-ehci" compatibility
string. The existing ehci-ppc-of driver is removed and the 440EPX
specific quirks are added to the ehci-platform driver.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
drivers/usb/host/Kconfig | 7 +-
drivers/usb/host/ehci-hcd.c | 5 -
drivers/usb/host/ehci-platform.c | 86 +++++++++++++-
drivers/usb/host/ehci-ppc-of.c | 236 --------------------------------------
4 files changed, 88 insertions(+), 246 deletions(-)
delete mode 100644 drivers/usb/host/ehci-ppc-of.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index b3f20d7..288fec1 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -189,12 +189,13 @@ config USB_EHCI_TEGRA
found in NVIDIA Tegra SoCs. The controllers are EHCI compliant.
config USB_EHCI_HCD_PPC_OF
- bool "EHCI support for PPC USB controller on OF platform bus"
+ bool "EHCI support for PPC USB controller on OF platform bus (DEPRECATED)"
depends on PPC_OF
default y
+ select USB_EHCI_HCD_PLATFORM
---help---
- Enables support for the USB controller present on the PowerPC
- OpenFirmware platform bus.
+ This option is deprecated now and the driver was removed, use
+ USB_EHCI_HCD_PLATFORM instead.
config USB_EHCI_SH
bool "EHCI support for SuperH USB controller"
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 86ab9fd..d0f384a 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1228,11 +1228,6 @@ MODULE_LICENSE ("GPL");
#define PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver
#endif
-#ifdef CONFIG_USB_EHCI_HCD_PPC_OF
-#include "ehci-ppc-of.c"
-#define OF_PLATFORM_DRIVER ehci_hcd_ppc_of_driver
-#endif
-
#ifdef CONFIG_XPS_USB_HCD_XILINX
#include "ehci-xilinx-of.c"
#define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index f6b790c..d9747fb 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -36,11 +36,33 @@
static const char hcd_name[] = "ehci-platform";
+/*
+ * 440EPx Errata USBH_3
+ * Fix: Enable Break Memory Transfer (BMT) in INSNREG3
+ */
+#define PPC440EPX_EHCI0_INSREG_BMT (0x1 << 0)
+static int
+ppc44x_enable_bmt(struct device_node *dn)
+{
+ __iomem u32 *insreg_virt;
+
+ insreg_virt = of_iomap(dn, 1);
+ if (!insreg_virt)
+ return -EINVAL;
+
+ out_be32(insreg_virt + 3, PPC440EPX_EHCI0_INSREG_BMT);
+
+ iounmap(insreg_virt);
+ return 0;
+}
+
static int ehci_platform_reset(struct usb_hcd *hcd)
{
struct platform_device *pdev = to_platform_device(hcd->self.controller);
struct usb_ehci_pdata *pdata = dev_get_platdata(&pdev->dev);
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct device_node *dn, *np;
+ struct resource res;
int retval;
hcd->has_tt = pdata->has_tt;
@@ -48,6 +70,43 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
ehci->big_endian_desc = pdata->big_endian_desc;
ehci->big_endian_mmio = pdata->big_endian_mmio;
+ /* Device tree properties if available will override platform data. */
+ dn = hcd_to_bus(hcd)->controller->of_node;
+ if (dn) {
+ if (of_get_property(dn, "big-endian", NULL)) {
+ ehci->big_endian_mmio = 1;
+ ehci->big_endian_desc = 1;
+ }
+ if (of_get_property(dn, "big-endian-regs", NULL))
+ ehci->big_endian_mmio = 1;
+ if (of_get_property(dn, "big-endian-desc", NULL))
+ ehci->big_endian_desc = 1;
+ }
+
+ np = of_find_compatible_node(NULL, NULL, "ibm,usb-ohci-440epx");
+ if (np != NULL) {
+ /* claim we really affected by usb23 erratum */
+ if (!of_address_to_resource(np, 0, &res))
+ ehci->ohci_hcctrl_reg =
+ devm_ioremap(&pdev->dev,
+ res.start + OHCI_HCCTRL_OFFSET,
+ OHCI_HCCTRL_LEN);
+ else
+ ehci_dbg(ehci, "%s: no ohci offset in fdt\n", __FILE__);
+ if (!ehci->ohci_hcctrl_reg) {
+ ehci_dbg(ehci, "%s: ioremap for ohci hcctrl failed\n",
+ __FILE__);
+ } else {
+ ehci->has_amcc_usb23 = 1;
+ }
+ }
+
+ if (of_device_is_compatible(dn, "ibm,usb-ehci-440epx")) {
+ retval = ppc44x_enable_bmt(dn);
+ ehci_dbg(ehci, "Break Memory Transfer (BMT) is %senabled!\n",
+ retval ? "NOT " : "");
+ }
+
if (pdata->pre_setup) {
retval = pdata->pre_setup(hcd);
if (retval < 0)
@@ -149,6 +208,9 @@ static int ehci_platform_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct device_node *np;
+ struct resource res;
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
@@ -159,6 +221,25 @@ static int ehci_platform_remove(struct platform_device *dev)
if (pdata == &ehci_platform_defaults)
dev->dev.platform_data = NULL;
+ /* use request_mem_region to test if the ohci driver is loaded. if so
+ * ensure the ohci core is operational.
+ */
+ if (ehci->has_amcc_usb23) {
+ np = of_find_compatible_node(NULL, NULL, "ibm,usb-ohci-440epx");
+ if (np != NULL) {
+ if (!of_address_to_resource(np, 0, &res))
+ if (!request_mem_region(res.start,
+ 0x4, hcd_name))
+ set_ohci_hcfs(ehci, 1);
+ else
+ release_mem_region(res.start, 0x4);
+ else
+ ehci_dbg(ehci, "%s: no ohci offset in fdt\n",
+ __FILE__);
+ of_node_put(np);
+ }
+ }
+
return 0;
}
@@ -203,9 +284,10 @@ static int ehci_platform_resume(struct device *dev)
#define ehci_platform_resume NULL
#endif /* CONFIG_PM */
-static const struct of_device_id vt8500_ehci_ids[] = {
+static const struct of_device_id ehci_platform_ids[] = {
{ .compatible = "via,vt8500-ehci", },
{ .compatible = "wm,prizm-ehci", },
+ { .compatible = "usb-ehci", },
{}
};
@@ -229,7 +311,7 @@ static struct platform_driver ehci_platform_driver = {
.owner = THIS_MODULE,
.name = "ehci-platform",
.pm = &ehci_platform_pm_ops,
- .of_match_table = vt8500_ehci_ids,
+ .of_match_table = ehci_platform_ids,
}
};
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
deleted file mode 100644
index 932293f..0000000
--- a/drivers/usb/host/ehci-ppc-of.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * EHCI HCD (Host Controller Driver) for USB.
- *
- * Bus Glue for PPC On-Chip EHCI driver on the of_platform bus
- * Tested on AMCC PPC 440EPx
- *
- * Valentine Barshak <vbarshak@ru.mvista.com>
- *
- * Based on "ehci-ppc-soc.c" by Stefan Roese <sr@denx.de>
- * and "ohci-ppc-of.c" by Sylvain Munaut <tnt@246tNt.com>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/err.h>
-#include <linux/signal.h>
-
-#include <linux/of.h>
-#include <linux/of_platform.h>
-
-
-static const struct hc_driver ehci_ppc_of_hc_driver = {
- .description = hcd_name,
- .product_desc = "OF EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- */
- .reset = ehci_setup,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
-
- /*
- * scheduling support
- */
- .get_frame_number = ehci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
-#endif
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-
-/*
- * 440EPx Errata USBH_3
- * Fix: Enable Break Memory Transfer (BMT) in INSNREG3
- */
-#define PPC440EPX_EHCI0_INSREG_BMT (0x1 << 0)
-static int
-ppc44x_enable_bmt(struct device_node *dn)
-{
- __iomem u32 *insreg_virt;
-
- insreg_virt = of_iomap(dn, 1);
- if (!insreg_virt)
- return -EINVAL;
-
- out_be32(insreg_virt + 3, PPC440EPX_EHCI0_INSREG_BMT);
-
- iounmap(insreg_virt);
- return 0;
-}
-
-
-static int ehci_hcd_ppc_of_probe(struct platform_device *op)
-{
- struct device_node *dn = op->dev.of_node;
- struct usb_hcd *hcd;
- struct ehci_hcd *ehci = NULL;
- struct resource res;
- int irq;
- int rv;
-
- struct device_node *np;
-
- if (usb_disabled())
- return -ENODEV;
-
- dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n");
-
- rv = of_address_to_resource(dn, 0, &res);
- if (rv)
- return rv;
-
- hcd = usb_create_hcd(&ehci_ppc_of_hc_driver, &op->dev, "PPC-OF USB");
- if (!hcd)
- return -ENOMEM;
-
- hcd->rsrc_start = res.start;
- hcd->rsrc_len = resource_size(&res);
-
- irq = irq_of_parse_and_map(dn, 0);
- if (irq == NO_IRQ) {
- printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__);
- rv = -EBUSY;
- goto err_irq;
- }
-
- hcd->regs = devm_ioremap_resource(&op->dev, &res);
- if (IS_ERR(hcd->regs)) {
- rv = PTR_ERR(hcd->regs);
- goto err_ioremap;
- }
-
- ehci = hcd_to_ehci(hcd);
- np = of_find_compatible_node(NULL, NULL, "ibm,usb-ohci-440epx");
- if (np != NULL) {
- /* claim we really affected by usb23 erratum */
- if (!of_address_to_resource(np, 0, &res))
- ehci->ohci_hcctrl_reg =
- devm_ioremap(&op->dev,
- res.start + OHCI_HCCTRL_OFFSET,
- OHCI_HCCTRL_LEN);
- else
- pr_debug("%s: no ohci offset in fdt\n", __FILE__);
- if (!ehci->ohci_hcctrl_reg) {
- pr_debug("%s: ioremap for ohci hcctrl failed\n", __FILE__);
- } else {
- ehci->has_amcc_usb23 = 1;
- }
- }
-
- if (of_get_property(dn, "big-endian", NULL)) {
- ehci->big_endian_mmio = 1;
- ehci->big_endian_desc = 1;
- }
- if (of_get_property(dn, "big-endian-regs", NULL))
- ehci->big_endian_mmio = 1;
- if (of_get_property(dn, "big-endian-desc", NULL))
- ehci->big_endian_desc = 1;
-
- ehci->caps = hcd->regs;
-
- if (of_device_is_compatible(dn, "ibm,usb-ehci-440epx")) {
- rv = ppc44x_enable_bmt(dn);
- ehci_dbg(ehci, "Break Memory Transfer (BMT) is %senabled!\n",
- rv ? "NOT ": "");
- }
-
- rv = usb_add_hcd(hcd, irq, 0);
- if (rv)
- goto err_ioremap;
-
- return 0;
-
-err_ioremap:
- irq_dispose_mapping(irq);
-err_irq:
- usb_put_hcd(hcd);
-
- return rv;
-}
-
-
-static int ehci_hcd_ppc_of_remove(struct platform_device *op)
-{
- struct usb_hcd *hcd = platform_get_drvdata(op);
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-
- struct device_node *np;
- struct resource res;
-
- dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n");
-
- usb_remove_hcd(hcd);
-
- irq_dispose_mapping(hcd->irq);
-
- /* use request_mem_region to test if the ohci driver is loaded. if so
- * ensure the ohci core is operational.
- */
- if (ehci->has_amcc_usb23) {
- np = of_find_compatible_node(NULL, NULL, "ibm,usb-ohci-440epx");
- if (np != NULL) {
- if (!of_address_to_resource(np, 0, &res))
- if (!request_mem_region(res.start,
- 0x4, hcd_name))
- set_ohci_hcfs(ehci, 1);
- else
- release_mem_region(res.start, 0x4);
- else
- pr_debug("%s: no ohci offset in fdt\n", __FILE__);
- of_node_put(np);
- }
- }
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-
-static const struct of_device_id ehci_hcd_ppc_of_match[] = {
- {
- .compatible = "usb-ehci",
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, ehci_hcd_ppc_of_match);
-
-
-static struct platform_driver ehci_hcd_ppc_of_driver = {
- .probe = ehci_hcd_ppc_of_probe,
- .remove = ehci_hcd_ppc_of_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ppc-of-ehci",
- .owner = THIS_MODULE,
- .of_match_table = ehci_hcd_ppc_of_match,
- },
-};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 6/8] IBM Currituck: Clean up board specific code before adding Akebono code
From: Alistair Popple @ 2013-11-22 2:08 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, Alistair Popple
In-Reply-To: <1385086057-10884-1-git-send-email-alistair@popple.id.au>
The IBM Akebono code uses the same initialisation functions as the
earlier Currituck board. Rather than create a copy of this code for
Akebono we will instead integrate support for it into the same file as
the Currituck code.
This patch renames the board support file and updates the 476FPE PCI
code to use a more generic name.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
arch/powerpc/platforms/44x/Kconfig | 4 +-
arch/powerpc/platforms/44x/Makefile | 2 +-
arch/powerpc/platforms/44x/currituck.c | 233 --------------------------------
arch/powerpc/platforms/44x/ppc476.c | 233 ++++++++++++++++++++++++++++++++
arch/powerpc/sysdev/ppc4xx_pci.c | 20 +--
arch/powerpc/sysdev/ppc4xx_pci.h | 4 +-
6 files changed, 248 insertions(+), 248 deletions(-)
delete mode 100644 arch/powerpc/platforms/44x/currituck.c
create mode 100644 arch/powerpc/platforms/44x/ppc476.c
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index d6c7506..156d474 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -194,7 +194,7 @@ config CURRITUCK
depends on PPC_47x
default n
select SWIOTLB
- select 476FPE
+ select 476
select PPC4xx_PCI_EXPRESS
help
This option enables support for the IBM Currituck (476fpe) evaluation board
@@ -314,7 +314,7 @@ config 460SX
select IBM_EMAC_ZMII
select IBM_EMAC_TAH
-config 476FPE
+config 476
bool
select PPC_FPU
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
index d03833a..f896b89 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
obj-$(CONFIG_ISS4xx) += iss4xx.o
obj-$(CONFIG_CANYONLANDS)+= canyonlands.o
-obj-$(CONFIG_CURRITUCK) += currituck.o
+obj-$(CONFIG_CURRITUCK) += ppc476.o
diff --git a/arch/powerpc/platforms/44x/currituck.c b/arch/powerpc/platforms/44x/currituck.c
deleted file mode 100644
index 7f1b71a..0000000
--- a/arch/powerpc/platforms/44x/currituck.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Currituck board specific routines
- *
- * Copyright © 2011 Tony Breeds IBM Corporation
- *
- * Based on earlier code:
- * Matt Porter <mporter@kernel.crashing.org>
- * Copyright 2002-2005 MontaVista Software Inc.
- *
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- * Copyright (c) 2003-2005 Zultys Technologies
- *
- * Rewritten and ported to the merged powerpc tree:
- * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
- * Copyright © 2011 David Kliekamp IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/rtc.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/ppc4xx.h>
-#include <asm/mpic.h>
-#include <asm/mmu.h>
-
-#include <linux/pci.h>
-
-static __initdata struct of_device_id ppc47x_of_bus[] = {
- { .compatible = "ibm,plb4", },
- { .compatible = "ibm,plb6", },
- { .compatible = "ibm,opb", },
- { .compatible = "ibm,ebc", },
- {},
-};
-
-/* The EEPROM is missing and the default values are bogus. This forces USB in
- * to EHCI mode */
-static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev)
-{
- if (of_machine_is_compatible("ibm,currituck")) {
- pci_write_config_dword(dev, 0xe0, 0x0114231f);
- pci_write_config_dword(dev, 0xe4, 0x00006c40);
- }
-}
-DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup);
-
-static int __init ppc47x_device_probe(void)
-{
- of_platform_bus_probe(NULL, ppc47x_of_bus, NULL);
-
- return 0;
-}
-machine_device_initcall(ppc47x, ppc47x_device_probe);
-
-/* We can have either UICs or MPICs */
-static void __init ppc47x_init_irq(void)
-{
- struct device_node *np;
-
- /* Find top level interrupt controller */
- for_each_node_with_property(np, "interrupt-controller") {
- if (of_get_property(np, "interrupts", NULL) == NULL)
- break;
- }
- if (np == NULL)
- panic("Can't find top level interrupt controller");
-
- /* Check type and do appropriate initialization */
- if (of_device_is_compatible(np, "chrp,open-pic")) {
- /* The MPIC driver will get everything it needs from the
- * device-tree, just pass 0 to all arguments
- */
- struct mpic *mpic =
- mpic_alloc(np, 0, MPIC_NO_RESET, 0, 0, " MPIC ");
- BUG_ON(mpic == NULL);
- mpic_init(mpic);
- ppc_md.get_irq = mpic_get_irq;
- } else
- panic("Unrecognized top level interrupt controller");
-}
-
-#ifdef CONFIG_SMP
-static void smp_ppc47x_setup_cpu(int cpu)
-{
- mpic_setup_this_cpu();
-}
-
-static int smp_ppc47x_kick_cpu(int cpu)
-{
- struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
- const u64 *spin_table_addr_prop;
- u32 *spin_table;
- extern void start_secondary_47x(void);
-
- BUG_ON(cpunode == NULL);
-
- /* Assume spin table. We could test for the enable-method in
- * the device-tree but currently there's little point as it's
- * our only supported method
- */
- spin_table_addr_prop =
- of_get_property(cpunode, "cpu-release-addr", NULL);
-
- if (spin_table_addr_prop == NULL) {
- pr_err("CPU%d: Can't start, missing cpu-release-addr !\n",
- cpu);
- return 1;
- }
-
- /* Assume it's mapped as part of the linear mapping. This is a bit
- * fishy but will work fine for now
- *
- * XXX: Is there any reason to assume differently?
- */
- spin_table = (u32 *)__va(*spin_table_addr_prop);
- pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table);
-
- spin_table[3] = cpu;
- smp_wmb();
- spin_table[1] = __pa(start_secondary_47x);
- mb();
-
- return 0;
-}
-
-static struct smp_ops_t ppc47x_smp_ops = {
- .probe = smp_mpic_probe,
- .message_pass = smp_mpic_message_pass,
- .setup_cpu = smp_ppc47x_setup_cpu,
- .kick_cpu = smp_ppc47x_kick_cpu,
- .give_timebase = smp_generic_give_timebase,
- .take_timebase = smp_generic_take_timebase,
-};
-
-static void __init ppc47x_smp_init(void)
-{
- if (mmu_has_feature(MMU_FTR_TYPE_47x))
- smp_ops = &ppc47x_smp_ops;
-}
-
-#else /* CONFIG_SMP */
-static void __init ppc47x_smp_init(void) { }
-#endif /* CONFIG_SMP */
-
-static void __init ppc47x_setup_arch(void)
-{
-
- /* No need to check the DMA config as we /know/ our windows are all of
- * RAM. Lets hope that doesn't change */
- swiotlb_detect_4g();
-
- ppc47x_smp_init();
-}
-
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init ppc47x_probe(void)
-{
- unsigned long root = of_get_flat_dt_root();
-
- if (!of_flat_dt_is_compatible(root, "ibm,currituck"))
- return 0;
-
- return 1;
-}
-
-static int board_rev = -1;
-static int __init ppc47x_get_board_rev(void)
-{
- u8 fpga_reg0;
- void *fpga;
- struct device_node *np;
-
- np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga");
- if (!np)
- goto fail;
-
- fpga = of_iomap(np, 0);
- of_node_put(np);
- if (!fpga)
- goto fail;
-
- fpga_reg0 = ioread8(fpga);
- board_rev = fpga_reg0 & 0x03;
- pr_info("%s: Found board revision %d\n", __func__, board_rev);
- iounmap(fpga);
- return 0;
-
-fail:
- pr_info("%s: Unable to find board revision\n", __func__);
- return 0;
-}
-machine_arch_initcall(ppc47x, ppc47x_get_board_rev);
-
-/* Use USB controller should have been hardware swizzled but it wasn't :( */
-static void ppc47x_pci_irq_fixup(struct pci_dev *dev)
-{
- if (dev->vendor == 0x1033 && (dev->device == 0x0035 ||
- dev->device == 0x00e0)) {
- if (board_rev == 0) {
- dev->irq = irq_create_mapping(NULL, 47);
- pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
- } else if (board_rev == 2) {
- dev->irq = irq_create_mapping(NULL, 49);
- pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
- } else {
- pr_alert("%s: Unknown board revision\n", __func__);
- }
- }
-}
-
-define_machine(ppc47x) {
- .name = "PowerPC 47x",
- .probe = ppc47x_probe,
- .progress = udbg_progress,
- .init_IRQ = ppc47x_init_irq,
- .setup_arch = ppc47x_setup_arch,
- .pci_irq_fixup = ppc47x_pci_irq_fixup,
- .restart = ppc4xx_reset_system,
- .calibrate_decr = generic_calibrate_decr,
-};
diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c
new file mode 100644
index 0000000..c6c5a6f
--- /dev/null
+++ b/arch/powerpc/platforms/44x/ppc476.c
@@ -0,0 +1,233 @@
+/*
+ * PowerPC 476FPE board specific routines
+ *
+ * Copyright © 2011 Tony Breeds IBM Corporation
+ *
+ * Based on earlier code:
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003-2005 Zultys Technologies
+ *
+ * Rewritten and ported to the merged powerpc tree:
+ * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
+ * Copyright © 2011 David Kliekamp IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/rtc.h>
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/time.h>
+#include <asm/uic.h>
+#include <asm/ppc4xx.h>
+#include <asm/mpic.h>
+#include <asm/mmu.h>
+
+#include <linux/pci.h>
+
+static struct of_device_id ppc47x_of_bus[] __initdata = {
+ { .compatible = "ibm,plb4", },
+ { .compatible = "ibm,plb6", },
+ { .compatible = "ibm,opb", },
+ { .compatible = "ibm,ebc", },
+ {},
+};
+
+/* The EEPROM is missing and the default values are bogus. This forces USB in
+ * to EHCI mode */
+static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev)
+{
+ if (of_machine_is_compatible("ibm,currituck")) {
+ pci_write_config_dword(dev, 0xe0, 0x0114231f);
+ pci_write_config_dword(dev, 0xe4, 0x00006c40);
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup);
+
+static int __init ppc47x_device_probe(void)
+{
+ of_platform_bus_probe(NULL, ppc47x_of_bus, NULL);
+
+ return 0;
+}
+machine_device_initcall(ppc47x, ppc47x_device_probe);
+
+/* We can have either UICs or MPICs */
+static void __init ppc47x_init_irq(void)
+{
+ struct device_node *np;
+
+ /* Find top level interrupt controller */
+ for_each_node_with_property(np, "interrupt-controller") {
+ if (of_get_property(np, "interrupts", NULL) == NULL)
+ break;
+ }
+ if (np == NULL)
+ panic("Can't find top level interrupt controller");
+
+ /* Check type and do appropriate initialization */
+ if (of_device_is_compatible(np, "chrp,open-pic")) {
+ /* The MPIC driver will get everything it needs from the
+ * device-tree, just pass 0 to all arguments
+ */
+ struct mpic *mpic =
+ mpic_alloc(np, 0, MPIC_NO_RESET, 0, 0, " MPIC ");
+ BUG_ON(mpic == NULL);
+ mpic_init(mpic);
+ ppc_md.get_irq = mpic_get_irq;
+ } else
+ panic("Unrecognized top level interrupt controller");
+}
+
+#ifdef CONFIG_SMP
+static void smp_ppc47x_setup_cpu(int cpu)
+{
+ mpic_setup_this_cpu();
+}
+
+static int smp_ppc47x_kick_cpu(int cpu)
+{
+ struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
+ const u64 *spin_table_addr_prop;
+ u32 *spin_table;
+ extern void start_secondary_47x(void);
+
+ BUG_ON(cpunode == NULL);
+
+ /* Assume spin table. We could test for the enable-method in
+ * the device-tree but currently there's little point as it's
+ * our only supported method
+ */
+ spin_table_addr_prop =
+ of_get_property(cpunode, "cpu-release-addr", NULL);
+
+ if (spin_table_addr_prop == NULL) {
+ pr_err("CPU%d: Can't start, missing cpu-release-addr !\n",
+ cpu);
+ return 1;
+ }
+
+ /* Assume it's mapped as part of the linear mapping. This is a bit
+ * fishy but will work fine for now
+ *
+ * XXX: Is there any reason to assume differently?
+ */
+ spin_table = (u32 *)__va(*spin_table_addr_prop);
+ pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table);
+
+ spin_table[3] = cpu;
+ smp_wmb();
+ spin_table[1] = __pa(start_secondary_47x);
+ mb();
+
+ return 0;
+}
+
+static struct smp_ops_t ppc47x_smp_ops = {
+ .probe = smp_mpic_probe,
+ .message_pass = smp_mpic_message_pass,
+ .setup_cpu = smp_ppc47x_setup_cpu,
+ .kick_cpu = smp_ppc47x_kick_cpu,
+ .give_timebase = smp_generic_give_timebase,
+ .take_timebase = smp_generic_take_timebase,
+};
+
+static void __init ppc47x_smp_init(void)
+{
+ if (mmu_has_feature(MMU_FTR_TYPE_47x))
+ smp_ops = &ppc47x_smp_ops;
+}
+
+#else /* CONFIG_SMP */
+static void __init ppc47x_smp_init(void) { }
+#endif /* CONFIG_SMP */
+
+static void __init ppc47x_setup_arch(void)
+{
+
+ /* No need to check the DMA config as we /know/ our windows are all of
+ * RAM. Lets hope that doesn't change */
+ swiotlb_detect_4g();
+
+ ppc47x_smp_init();
+}
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init ppc47x_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "ibm,currituck"))
+ return 0;
+
+ return 1;
+}
+
+static int board_rev = -1;
+static int __init ppc47x_get_board_rev(void)
+{
+ u8 fpga_reg0;
+ void *fpga;
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga");
+ if (!np)
+ goto fail;
+
+ fpga = of_iomap(np, 0);
+ of_node_put(np);
+ if (!fpga)
+ goto fail;
+
+ fpga_reg0 = ioread8(fpga);
+ board_rev = fpga_reg0 & 0x03;
+ pr_info("%s: Found board revision %d\n", __func__, board_rev);
+ iounmap(fpga);
+ return 0;
+
+fail:
+ pr_info("%s: Unable to find board revision\n", __func__);
+ return 0;
+}
+machine_arch_initcall(ppc47x, ppc47x_get_board_rev);
+
+/* Use USB controller should have been hardware swizzled but it wasn't :( */
+static void ppc47x_pci_irq_fixup(struct pci_dev *dev)
+{
+ if (dev->vendor == 0x1033 && (dev->device == 0x0035 ||
+ dev->device == 0x00e0)) {
+ if (board_rev == 0) {
+ dev->irq = irq_create_mapping(NULL, 47);
+ pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
+ } else if (board_rev == 2) {
+ dev->irq = irq_create_mapping(NULL, 49);
+ pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
+ } else {
+ pr_alert("%s: Unknown board revision\n", __func__);
+ }
+ }
+}
+
+define_machine(ppc47x) {
+ .name = "PowerPC 47x",
+ .probe = ppc47x_probe,
+ .progress = udbg_progress,
+ .init_IRQ = ppc47x_init_irq,
+ .setup_arch = ppc47x_setup_arch,
+ .pci_irq_fixup = ppc47x_pci_irq_fixup,
+ .restart = ppc4xx_reset_system,
+ .calibrate_decr = generic_calibrate_decr,
+};
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 64603a1..dba5e4d 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -1366,13 +1366,13 @@ static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata =
#endif /* CONFIG_40x */
-#ifdef CONFIG_476FPE
-static int __init ppc_476fpe_pciex_core_init(struct device_node *np)
+#ifdef CONFIG_476
+static int __init ppc476_pciex_core_init(struct device_node *np)
{
return 4;
}
-static void __init ppc_476fpe_pciex_check_link(struct ppc4xx_pciex_port *port)
+static void __init ppc476_pciex_check_link(struct ppc4xx_pciex_port *port)
{
u32 timeout_ms = 20;
u32 val = 0, mask = (PECFG_TLDLP_LNKUP|PECFG_TLDLP_PRESENT);
@@ -1405,12 +1405,12 @@ static void __init ppc_476fpe_pciex_check_link(struct ppc4xx_pciex_port *port)
return;
}
-static struct ppc4xx_pciex_hwops ppc_476fpe_pcie_hwops __initdata =
+static struct ppc4xx_pciex_hwops ppc476_pcie_hwops __initdata =
{
- .core_init = ppc_476fpe_pciex_core_init,
- .check_link = ppc_476fpe_pciex_check_link,
+ .core_init = ppc476_pciex_core_init,
+ .check_link = ppc476_pciex_check_link,
};
-#endif /* CONFIG_476FPE */
+#endif /* CONFIG_476 */
/* Check that the core has been initied and if not, do it */
static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
@@ -1439,9 +1439,9 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
if (of_device_is_compatible(np, "ibm,plb-pciex-405ex"))
ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops;
#endif
-#ifdef CONFIG_476FPE
+#ifdef CONFIG_476
if (of_device_is_compatible(np, "ibm,plb-pciex-476fpe"))
- ppc4xx_pciex_hwops = &ppc_476fpe_pcie_hwops;
+ ppc4xx_pciex_hwops = &ppc476_pcie_hwops;
#endif
if (ppc4xx_pciex_hwops == NULL) {
printk(KERN_WARNING "PCIE: unknown host type %s\n",
@@ -1753,7 +1753,7 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
| DCRO_PEGPL_OMRxMSKL_VAL);
else if (of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe"))
dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
- sa | DCRO_PEGPL_476FPE_OMR1MSKL_UOT
+ sa | DCRO_PEGPL_476_OMR1MSKL_UOT
| DCRO_PEGPL_OMRxMSKL_VAL);
else
dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h
index bb48219..6412011 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.h
+++ b/arch/powerpc/sysdev/ppc4xx_pci.h
@@ -476,12 +476,12 @@
#define DCRO_PEGPL_OMR1MSKL_UOT 0x00000002
#define DCRO_PEGPL_OMR3MSKL_IO 0x00000002
-/* 476FPE */
+/* PPC476 */
#define PCCFG_LCPA 0x270
#define PECFG_TLDLP 0x3F8
#define PECFG_TLDLP_LNKUP 0x00000008
#define PECFG_TLDLP_PRESENT 0x00000010
-#define DCRO_PEGPL_476FPE_OMR1MSKL_UOT 0x00000004
+#define DCRO_PEGPL_476_OMR1MSKL_UOT 0x00000004
/* SDR Bit Mappings */
#define PESDRx_RCSSET_HLDPLB 0x10000000
--
1.7.10.4
^ permalink raw reply related
* [PATCH 7/8] IBM Akebono: Add the Akebono platform
From: Alistair Popple @ 2013-11-22 2:08 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, Alistair Popple
In-Reply-To: <1385086057-10884-1-git-send-email-alistair@popple.id.au>
This patch adds support for the IBM Akebono board.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
.../devicetree/bindings/powerpc/4xx/akebono.txt | 54 +++
arch/powerpc/boot/Makefile | 3 +
arch/powerpc/boot/dcr.h | 4 +
arch/powerpc/boot/dts/akebono.dts | 385 ++++++++++++++++++++
arch/powerpc/boot/treeboot-akebono.c | 179 +++++++++
arch/powerpc/boot/wrapper | 3 +
arch/powerpc/configs/44x/akebono_defconfig | 148 ++++++++
arch/powerpc/platforms/44x/Kconfig | 26 ++
arch/powerpc/platforms/44x/Makefile | 1 +
arch/powerpc/platforms/44x/ppc476.c | 112 ++++--
arch/powerpc/sysdev/ppc4xx_pci.c | 13 +-
11 files changed, 902 insertions(+), 26 deletions(-)
create mode 100644 Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
create mode 100644 arch/powerpc/boot/dts/akebono.dts
create mode 100644 arch/powerpc/boot/treeboot-akebono.c
create mode 100644 arch/powerpc/configs/44x/akebono_defconfig
diff --git a/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt b/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
new file mode 100644
index 0000000..75adb84
--- /dev/null
+++ b/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
@@ -0,0 +1,54 @@
+
+IBM Akebono board device tree
+=============================
+
+The IBM Akebono board is a development board for the PPC476GTR SoC.
+
+0) The root node
+
+ Required properties:
+
+ - model : "ibm,akebono".
+ - compatible : "ibm,akebono" , "ibm,476gtr".
+
+1.a) The Secure Digital Host Controller Interface (SDHCI) node
+
+ Represent the Secure Digital Host Controller Interfaces.
+
+ Required properties:
+
+ - compatible : should be "ibm,476gtr-sdhci","sdhci".
+ - reg : should contain the SDHCI registers location and length.
+ - interrupt-parent : a phandle for the interrupt controller.
+ - interrupts : should contain the SDHCI interrupt.
+
+1.b) The Advanced Host Controller Interface (AHCI) SATA node
+
+ Represents the advanced host controller SATA interface.
+
+ Required properties:
+
+ - compatible : should be "ibm,476gtr-ahci".
+ - reg : should contain the AHCI registers location and length.
+ - interrupt-parent : a phandle for the interrupt controller.
+ - interrupts : should contain the AHCI interrupt.
+
+1.c) The FPGA node
+
+ The Akebono board stores some board information such as the revision
+ number in an FPGA which is represented by this node.
+
+ Required properties:
+
+ - compatible : should be "ibm,akebono-fpga".
+ - reg : should contain the FPGA registers location and length.
+
+1.d) The AVR node
+
+ The Akebono board has an Atmel AVR microprocessor attached to the I2C
+ bus as a power controller for the board.
+
+ Required properties:
+
+ - compatible : should be "ibm,akebono-avr".
+ - reg : should contain the I2C bus address for the AVR.
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 15ca225..645ff21 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -46,6 +46,7 @@ $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-currituck.o: BOOTCFLAGS += -mcpu=405
+$(obj)/treeboot-akebono.o: BOOTCFLAGS += -mcpu=405
$(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405
@@ -85,6 +86,7 @@ src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c treeboot-bamboo.c \
cuboot-taishan.c cuboot-katmai.c \
cuboot-warp.c cuboot-yosemite.c \
treeboot-iss4xx.c treeboot-currituck.c \
+ treeboot-akebono.c \
simpleboot.c fixed-head.S virtex.c
src-plat-$(CONFIG_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c
src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c
@@ -235,6 +237,7 @@ image-$(CONFIG_YOSEMITE) += cuImage.yosemite
image-$(CONFIG_ISS4xx) += treeImage.iss4xx \
treeImage.iss4xx-mpic
image-$(CONFIG_CURRITUCK) += treeImage.currituck
+image-$(CONFIG_AKEBONO) += treeImage.akebono
# Board ports in arch/powerpc/platform/8xx/Kconfig
image-$(CONFIG_MPC86XADS) += cuImage.mpc866ads
diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h
index cc73f7a..bf8f4ed 100644
--- a/arch/powerpc/boot/dcr.h
+++ b/arch/powerpc/boot/dcr.h
@@ -15,6 +15,10 @@
asm volatile("mfdcrx %0,%1" : "=r"(rval) : "r"(rn)); \
rval; \
})
+#define mtdcrx(rn, val) \
+ ({ \
+ asm volatile("mtdcrx %0,%1" : : "r"(rn), "r" (val)); \
+ })
/* 440GP/440GX SDRAM controller DCRs */
#define DCRN_SDRAM0_CFGADDR 0x010
diff --git a/arch/powerpc/boot/dts/akebono.dts b/arch/powerpc/boot/dts/akebono.dts
new file mode 100644
index 0000000..6dd47e9
--- /dev/null
+++ b/arch/powerpc/boot/dts/akebono.dts
@@ -0,0 +1,385 @@
+/*
+ * Device Tree Source for IBM Embedded PPC 476 Platform
+ *
+ * Copyright © 2013 Tony Breeds IBM Corporation
+ * Copyright © 2013 Alistair Popple IBM Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x01f00000 0x00100000; // spin table
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ model = "ibm,akebono";
+ compatible = "ibm,akebono", "ibm,476gtr";
+ dcr-parent = <&{/cpus/cpu@0}>;
+
+ aliases {
+ serial0 = &UART0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ model = "PowerPC,476";
+ reg = <0>;
+ clock-frequency = <1600000000>; // 1.6 GHz
+ timebase-frequency = <100000000>; // 100Mhz
+ i-cache-line-size = <32>;
+ d-cache-line-size = <32>;
+ i-cache-size = <32768>;
+ d-cache-size = <32768>;
+ dcr-controller;
+ dcr-access-method = "native";
+ status = "ok";
+ };
+ cpu@1 {
+ device_type = "cpu";
+ model = "PowerPC,476";
+ reg = <1>;
+ clock-frequency = <1600000000>; // 1.6 GHz
+ timebase-frequency = <100000000>; // 100Mhz
+ i-cache-line-size = <32>;
+ d-cache-line-size = <32>;
+ i-cache-size = <32768>;
+ d-cache-size = <32768>;
+ dcr-controller;
+ dcr-access-method = "native";
+ status = "disabled";
+ enable-method = "spin-table";
+ cpu-release-addr = <0x0 0x01f00000>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x0>; // filled in by zImage
+ };
+
+ MPIC: interrupt-controller {
+ compatible = "chrp,open-pic";
+ interrupt-controller;
+ dcr-reg = <0xffc00000 0x00040000>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ single-cpu-affinity;
+ };
+
+ plb {
+ compatible = "ibm,plb6";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ clock-frequency = <200000000>; // 200Mhz
+
+ MAL0: mcmal {
+ compatible = "ibm,mcmal-476gtr", "ibm,mcmal2";
+ dcr-reg = <0xc0000000 0x062>;
+ num-tx-chans = <1>;
+ num-rx-chans = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-parent = <&MPIC>;
+ interrupts = < /*TXEOB*/ 77 0x4
+ /*RXEOB*/ 78 0x4
+ /*SERR*/ 76 0x4
+ /*TXDE*/ 79 0x4
+ /*RXDE*/ 80 0x4>;
+ };
+
+ SATA0: sata@30000010000 {
+ compatible = "ibm,476gtr-ahci";
+ reg = <0x300 0x00010000 0x0 0x10000>;
+ interrupt-parent = <&MPIC>;
+ interrupts = <93 2>;
+ };
+
+ EHCI0: ehci@30010000000 {
+ compatible = "ibm,476gtr-ehci", "usb-ehci";
+ reg = <0x300 0x10000000 0x0 0x10000>;
+ interrupt-parent = <&MPIC>;
+ interrupts = <85 2>;
+ };
+
+ SD0: sd@30000000000 {
+ compatible = "ibm,476gtr-sdhci", "sdhci";
+ reg = <0x300 0x00000000 0x0 0x10000>;
+ interrupts = <91 2>;
+ interrupt-parent = <&MPIC>;
+ };
+
+ OHCI0: ohci@30010010000 {
+ compatible = "ibm,476gtr-ohci", "usb-ohci";
+ reg = <0x300 0x10010000 0x0 0x10000>;
+ interrupt-parent = <&MPIC>;
+ interrupts = <89 1>;
+ };
+
+ OHCI1: ohci@30010020000 {
+ compatible = "ibm,476gtr-ohci", "usb-ohci";
+ reg = <0x300 0x10020000 0x0 0x10000>;
+ interrupt-parent = <&MPIC>;
+ interrupts = <88 1>;
+ };
+
+ POB0: opb {
+ compatible = "ibm,opb-4xx", "ibm,opb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /* Wish there was a nicer way of specifying a full
+ * 32-bit range
+ */
+ ranges = <0x00000000 0x0000033f 0x00000000 0x80000000
+ 0x80000000 0x0000033f 0x80000000 0x80000000>;
+ clock-frequency = <100000000>;
+
+ RGMII0: emac-rgmii-wol@50004 {
+ compatible = "ibm,rgmii-wol-476gtr", "ibm,rgmii-wol";
+ reg = <0x50004 0x00000008>;
+ has-mdio;
+ };
+
+ EMAC0: ethernet@30000 {
+ device_type = "network";
+ compatible = "ibm,emac-476gtr", "ibm,emac4sync";
+ interrupt-parent = <&EMAC0>;
+ interrupts = <0x0 0x1>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = </*Status*/ 0x0 &MPIC 81 0x4
+ /*Wake*/ 0x1 &MPIC 82 0x4>;
+ reg = <0x30000 0x78>;
+
+ /* local-mac-address will normally be added by
+ * the wrapper. If your device doesn't support
+ * passing data to the wrapper (in the form
+ * local-mac-addr=<hwaddr>) then you will need
+ * to set it manually here. */
+ //local-mac-address = [000000000000];
+
+ mal-device = <&MAL0>;
+ mal-tx-channel = <0>;
+ mal-rx-channel = <0>;
+ cell-index = <0>;
+ max-frame-size = <9000>;
+ rx-fifo-size = <4096>;
+ tx-fifo-size = <2048>;
+ rx-fifo-size-gige = <16384>;
+ phy-mode = "rgmii";
+ phy-map = <0x00000000>;
+ rgmii-wol-device = <&RGMII0>;
+ has-inverted-stacr-oc;
+ has-new-stacr-staopc;
+ };
+
+ UART0: serial@10000 {
+ device_type = "serial";
+ compatible = "ns16750", "ns16550";
+ reg = <0x10000 0x00000008>;
+ virtual-reg = <0xe8010000>;
+ clock-frequency = <1851851>;
+ current-speed = <38400>;
+ interrupt-parent = <&MPIC>;
+ interrupts = <39 2>;
+ };
+
+ IIC0: i2c@00000000 {
+ compatible = "ibm,iic-476gtr", "ibm,iic";
+ reg = <0x0 0x00000020>;
+ interrupt-parent = <&MPIC>;
+ interrupts = <37 2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rtc@68 {
+ compatible = "stm,m41t80", "m41st85";
+ reg = <0x68>;
+ };
+ };
+
+ IIC1: i2c@00000100 {
+ compatible = "ibm,iic-476gtr", "ibm,iic";
+ reg = <0x100 0x00000020>;
+ interrupt-parent = <&MPIC>;
+ interrupts = <38 2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ avr@58 {
+ compatible = "ibm,akebono-avr";
+ reg = <0x58>;
+ };
+ };
+
+ FPGA0: fpga@ebc00000 {
+ compatible = "ibm,akebono-fpga";
+ reg = <0xebc00000 0x8>;
+ };
+ };
+
+ PCIE0: pciex@10100000000 {
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb-pciex-476gtr", "ibm,plb-pciex";
+ primary;
+ port = <0x0>; /* port number */
+ reg = <0x00000101 0x00000000 0x0 0x10000000 /* Config space access */
+ 0x00000100 0x00000000 0x0 0x00001000>; /* UTL Registers space access */
+ dcr-reg = <0xc0 0x20>;
+
+// pci_space < pci_addr > < cpu_addr > < size >
+ ranges = <0x02000000 0x00000000 0x80000000 0x00000110 0x80000000 0x0 0x80000000
+ 0x01000000 0x0 0x0 0x00000140 0x0 0x0 0x00010000>;
+
+ /* Inbound starting at 0 to memsize filled in by zImage */
+ dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>;
+
+ /* This drives busses 0 to 0xf */
+ bus-range = <0x0 0xf>;
+
+ /* Legacy interrupts (note the weird polarity, the bridge seems
+ * to invert PCIe legacy interrupts).
+ * We are de-swizzling here because the numbers are actually for
+ * port of the root complex virtual P2P bridge. But I want
+ * to avoid putting a node for it in the tree, so the numbers
+ * below are basically de-swizzled numbers.
+ * The real slot is on idsel 0, so the swizzling is 1:1
+ */
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0 0x0 0x0 0x1 &MPIC 45 0x2 /* int A */
+ 0x0 0x0 0x0 0x2 &MPIC 46 0x2 /* int B */
+ 0x0 0x0 0x0 0x3 &MPIC 47 0x2 /* int C */
+ 0x0 0x0 0x0 0x4 &MPIC 48 0x2 /* int D */>;
+ };
+
+ PCIE1: pciex@20100000000 {
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb-pciex-476gtr", "ibm,plb-pciex";
+ primary;
+ port = <0x1>; /* port number */
+ reg = <0x00000201 0x00000000 0x0 0x10000000 /* Config space access */
+ 0x00000200 0x00000000 0x0 0x00001000>; /* UTL Registers space access */
+ dcr-reg = <0x100 0x20>;
+
+// pci_space < pci_addr > < cpu_addr > < size >
+ ranges = <0x02000000 0x00000000 0x80000000 0x00000210 0x80000000 0x0 0x80000000
+ 0x01000000 0x0 0x0 0x00000240 0x0 0x0 0x00010000>;
+
+ /* Inbound starting at 0 to memsize filled in by zImage */
+ dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>;
+
+ /* This drives busses 0 to 0xf */
+ bus-range = <0x0 0xf>;
+
+ /* Legacy interrupts (note the weird polarity, the bridge seems
+ * to invert PCIe legacy interrupts).
+ * We are de-swizzling here because the numbers are actually for
+ * port of the root complex virtual P2P bridge. But I want
+ * to avoid putting a node for it in the tree, so the numbers
+ * below are basically de-swizzled numbers.
+ * The real slot is on idsel 0, so the swizzling is 1:1
+ */
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0 0x0 0x0 0x1 &MPIC 53 0x2 /* int A */
+ 0x0 0x0 0x0 0x2 &MPIC 54 0x2 /* int B */
+ 0x0 0x0 0x0 0x3 &MPIC 55 0x2 /* int C */
+ 0x0 0x0 0x0 0x4 &MPIC 56 0x2 /* int D */>;
+ };
+
+ PCIE2: pciex@18100000000 {
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb-pciex-476gtr", "ibm,plb-pciex";
+ primary;
+ port = <0x2>; /* port number */
+ reg = <0x00000181 0x00000000 0x0 0x10000000 /* Config space access */
+ 0x00000180 0x00000000 0x0 0x00001000>; /* UTL Registers space access */
+ dcr-reg = <0xe0 0x20>;
+
+// pci_space < pci_addr > < cpu_addr > < size >
+ ranges = <0x02000000 0x00000000 0x80000000 0x00000190 0x80000000 0x0 0x80000000
+ 0x01000000 0x0 0x0 0x000001c0 0x0 0x0 0x00010000>;
+
+ /* Inbound starting at 0 to memsize filled in by zImage */
+ dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>;
+
+ /* This drives busses 0 to 0xf */
+ bus-range = <0x0 0xf>;
+
+ /* Legacy interrupts (note the weird polarity, the bridge seems
+ * to invert PCIe legacy interrupts).
+ * We are de-swizzling here because the numbers are actually for
+ * port of the root complex virtual P2P bridge. But I want
+ * to avoid putting a node for it in the tree, so the numbers
+ * below are basically de-swizzled numbers.
+ * The real slot is on idsel 0, so the swizzling is 1:1
+ */
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0 0x0 0x0 0x1 &MPIC 61 0x2 /* int A */
+ 0x0 0x0 0x0 0x2 &MPIC 62 0x2 /* int B */
+ 0x0 0x0 0x0 0x3 &MPIC 63 0x2 /* int C */
+ 0x0 0x0 0x0 0x4 &MPIC 64 0x2 /* int D */>;
+ };
+
+ PCIE3: pciex@28100000000 {
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb-pciex-476gtr", "ibm,plb-pciex";
+ primary;
+ port = <0x3>; /* port number */
+ reg = <0x00000281 0x00000000 0x0 0x10000000 /* Config space access */
+ 0x00000280 0x00000000 0x0 0x00001000>; /* UTL Registers space access */
+ dcr-reg = <0x120 0x20>;
+
+// pci_space < pci_addr > < cpu_addr > < size >
+ ranges = <0x02000000 0x00000000 0x80000000 0x00000290 0x80000000 0x0 0x80000000
+ 0x01000000 0x0 0x0 0x000002c0 0x0 0x0 0x00010000>;
+
+ /* Inbound starting at 0 to memsize filled in by zImage */
+ dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>;
+
+ /* This drives busses 0 to 0xf */
+ bus-range = <0x0 0xf>;
+
+ /* Legacy interrupts (note the weird polarity, the bridge seems
+ * to invert PCIe legacy interrupts).
+ * We are de-swizzling here because the numbers are actually for
+ * port of the root complex virtual P2P bridge. But I want
+ * to avoid putting a node for it in the tree, so the numbers
+ * below are basically de-swizzled numbers.
+ * The real slot is on idsel 0, so the swizzling is 1:1
+ */
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0 0x0 0x0 0x1 &MPIC 69 0x2 /* int A */
+ 0x0 0x0 0x0 0x2 &MPIC 70 0x2 /* int B */
+ 0x0 0x0 0x0 0x3 &MPIC 71 0x2 /* int C */
+ 0x0 0x0 0x0 0x4 &MPIC 72 0x2 /* int D */>;
+ };
+ };
+
+ chosen {
+ linux,stdout-path = &UART0;
+ };
+};
diff --git a/arch/powerpc/boot/treeboot-akebono.c b/arch/powerpc/boot/treeboot-akebono.c
new file mode 100644
index 0000000..4bc6f8d
--- /dev/null
+++ b/arch/powerpc/boot/treeboot-akebono.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 2013 Tony Breeds IBM Corporation
+ * Copyright © 2013 Alistair Popple IBM Corporation
+ *
+ * Based on earlier code:
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 Zultys Technologies
+ *
+ * Copyright 2007 David Gibson, IBM Corporation.
+ * Copyright 2010 Ben. Herrenschmidt, IBM Corporation.
+ * Copyright © 2011 David Kleikamp IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+#include "reg.h"
+#include "io.h"
+#include "dcr.h"
+#include "4xx.h"
+#include "44x.h"
+#include "libfdt.h"
+
+BSS_STACK(4096);
+
+#define MAX_RANKS 0x4
+#define DDR3_MR0CF 0x80010011U
+#define CCTL0_MCO2 0x8000080FU
+#define CCTL0_MCO3 0x80000810U
+#define CCTL0_MCO4 0x80000811U
+#define CCTL0_MCO5 0x80000812U
+#define CCTL0_MCO6 0x80000813U
+
+static unsigned long long ibm_akebono_memsize;
+static long long unsigned mac_addr;
+
+static unsigned long long ibm_akebono_detect_memsize(void)
+{
+ u32 reg;
+ unsigned i;
+ unsigned long long memsize = 0;
+
+ for (i = 0; i < MAX_RANKS; i++) {
+ reg = mfdcrx(DDR3_MR0CF + i);
+
+ if (!(reg & 1))
+ continue;
+
+ reg &= 0x0000f000;
+ reg >>= 12;
+ memsize += (0x800000ULL << reg);
+ }
+
+ return memsize;
+}
+
+static void ibm_akebono_fixups(void)
+{
+ void *emac;
+ u32 reg;
+ void *devp = finddevice("/");
+ u32 dma_ranges[7];
+
+ dt_fixup_memory(0x0ULL, ibm_akebono_memsize);
+
+ while ((devp = find_node_by_devtype(devp, "pci"))) {
+ if (getprop(devp, "dma-ranges", dma_ranges,
+ sizeof(dma_ranges)) < 0) {
+ printf("%s: Failed to get dma-ranges\r\n", __func__);
+ continue;
+ }
+
+ dma_ranges[5] = ibm_akebono_memsize >> 32;
+ dma_ranges[6] = ibm_akebono_memsize & 0xffffffffUL;
+
+ setprop(devp, "dma-ranges", dma_ranges, sizeof(dma_ranges));
+ }
+
+ /* Fixup the SD timeout frequency */
+ mtdcrx(CCTL0_MCO4, 0x1);
+
+ /* Disable SD high-speed mode (which seems to be broken) */
+ reg = mfdcrx(CCTL0_MCO2) & ~0x2;
+ mtdcrx(CCTL0_MCO2, reg);
+
+ /* Set the MAC address */
+ emac = finddevice("/plb/opb/ethernet");
+ if (emac > 0) {
+ if (mac_addr)
+ setprop(emac, "local-mac-address",
+ ((u8 *) &mac_addr) + 2 , 6);
+ }
+}
+
+/* FIXME */
+#define SPRN_PIR 0x11E /* Processor Indentification Register */
+#define USERDATA_LEN 256 /* Length of userdata passed in by PIBS */
+void platform_init(char *userdata)
+{
+ unsigned long end_of_ram, avail_ram;
+ u32 pir_reg;
+ int node, size;
+ const u32 *timebase;
+ int len, i, userdata_len;
+ char *end;
+
+ userdata[USERDATA_LEN - 1] = '\0';
+ userdata_len = strlen(userdata);
+ for (i = 0; i < userdata_len; i++) {
+ if (strncmp(&userdata[i], "local-mac-addr=", 15) == 0) {
+ if (i > 0 && userdata[i - 1] != ' ') {
+ /* We've only found a substring ending
+ * with local-mac-addr so this isn't
+ * our mac address. */
+ continue;
+ }
+
+ mac_addr = strtoull(&userdata[i + 15], &end, 16);
+
+ /* Remove the "local-mac-addr=<...>" from the kernel
+ * command line, including the tailing space if
+ * present. */
+ if (*end == ' ')
+ end++;
+
+ len = ((int) end) - ((int) &userdata[i]);
+ memmove(&userdata[i], end,
+ userdata_len - (len + i) + 1);
+ break;
+ }
+ }
+
+ loader_info.cmdline = userdata;
+ loader_info.cmdline_len = 256;
+
+ ibm_akebono_memsize = ibm_akebono_detect_memsize();
+ if (ibm_akebono_memsize >> 32)
+ end_of_ram = ~0UL;
+ else
+ end_of_ram = ibm_akebono_memsize;
+ avail_ram = end_of_ram - (unsigned long)_end;
+
+ simple_alloc_init(_end, avail_ram, 128, 64);
+ platform_ops.fixups = ibm_akebono_fixups;
+ platform_ops.exit = ibm44x_dbcr_reset;
+ pir_reg = mfspr(SPRN_PIR);
+
+ /* Make sure FDT blob is sane */
+ if (fdt_check_header(_dtb_start) != 0)
+ fatal("Invalid device tree blob\n");
+
+ node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
+ "cpu", sizeof("cpu"));
+ if (!node)
+ fatal("Cannot find cpu node\n");
+ timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size);
+ if (timebase && (size == 4))
+ timebase_period_ns = 1000000000 / *timebase;
+
+ fdt_set_boot_cpuid_phys(_dtb_start, pir_reg);
+ fdt_init(_dtb_start);
+
+ serial_console_init();
+}
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index cd7af84..1260819 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -249,6 +249,9 @@ gamecube|wii)
treeboot-currituck)
link_address='0x1000000'
;;
+treeboot-akebono)
+ link_address='0x1000000'
+ ;;
treeboot-iss4xx-mpic)
platformo="$object/treeboot-iss4xx.o"
;;
diff --git a/arch/powerpc/configs/44x/akebono_defconfig b/arch/powerpc/configs/44x/akebono_defconfig
new file mode 100644
index 0000000..7e2530c
--- /dev/null
+++ b/arch/powerpc/configs/44x/akebono_defconfig
@@ -0,0 +1,148 @@
+CONFIG_44x=y
+CONFIG_SMP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_SLUB_CPU_PARTIAL is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_POWERNV_MSI is not set
+CONFIG_PPC_47x=y
+# CONFIG_EBONY is not set
+CONFIG_AKEBONO=y
+CONFIG_HIGHMEM=y
+CONFIG_HZ_100=y
+CONFIG_IRQ_ALL_CPUS=y
+# CONFIG_COMPACTION is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
+# CONFIG_SUSPEND is not set
+CONFIG_PCI_MSI=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SATA_PMP is not set
+# CONFIG_ATA_SFF is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_IBM_EMAC=y
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_NET_VENDOR_XILINX is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+# CONFIG_USB_DEFAULT_PERSIST is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PCI is not set
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_M41T80=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_VFAT_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_DEFAULT="n"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0x00010000
+CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x33f
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1_PPC=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 156d474..9d20800 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -199,6 +199,32 @@ config CURRITUCK
help
This option enables support for the IBM Currituck (476fpe) evaluation board
+config AKEBONO
+ bool "IBM Akebono (476gtr) Support"
+ depends on PPC_47x
+ default n
+ select SWIOTLB
+ select 476
+ select PPC4xx_PCI_EXPRESS
+ select I2C
+ select I2C_IBM_IIC
+ select NETDEVICES
+ select ETHERNET
+ select NET_VENDOR_IBM
+ select IBM_EMAC_EMAC4
+ select IBM_EMAC_RGMII_WOL
+ select USB
+ select USB_OHCI_HCD_PLATFORM
+ select USB_EHCI_HCD_PLATFORM
+ select MMC_SDHCI
+ select MMC_SDHCI_PLTFM
+ select MMC_SDHCI_OF_476GTR
+ select ATA
+ select SATA_AHCI_PLATFORM
+ help
+ This option enables support for the IBM Akebono (476gtr) evaluation board
+
+
config ICON
bool "Icon"
depends on 44x
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
index f896b89..26d35b5 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
obj-$(CONFIG_ISS4xx) += iss4xx.o
obj-$(CONFIG_CANYONLANDS)+= canyonlands.o
obj-$(CONFIG_CURRITUCK) += ppc476.o
+obj-$(CONFIG_AKEBONO) += ppc476.o
diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c
index c6c5a6f..33986c1 100644
--- a/arch/powerpc/platforms/44x/ppc476.c
+++ b/arch/powerpc/platforms/44x/ppc476.c
@@ -1,7 +1,8 @@
/*
* PowerPC 476FPE board specific routines
*
- * Copyright © 2011 Tony Breeds IBM Corporation
+ * Copyright © 2013 Tony Breeds IBM Corporation
+ * Copyright © 2013 Alistair Popple IBM Corporation
*
* Based on earlier code:
* Matt Porter <mporter@kernel.crashing.org>
@@ -35,6 +36,7 @@
#include <asm/mmu.h>
#include <linux/pci.h>
+#include <linux/i2c.h>
static struct of_device_id ppc47x_of_bus[] __initdata = {
{ .compatible = "ibm,plb4", },
@@ -55,15 +57,69 @@ static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup);
+/* Akebono has an AVR microcontroller attached to the I2C bus
+ * which is used to power off/reset the system. */
+
+/* AVR I2C Commands */
+#define AVR_PWRCTL_CMD (0x26)
+
+/* Flags for the power control I2C commands */
+#define AVR_PWRCTL_PWROFF (0x01)
+#define AVR_PWRCTL_RESET (0x02)
+
+static struct i2c_client *avr_i2c_client;
+static void avr_halt_system(int pwrctl_flags)
+{
+ /* Request the AVR to reset the system */
+ i2c_smbus_write_byte_data(avr_i2c_client,
+ AVR_PWRCTL_CMD, pwrctl_flags);
+
+ /* Wait for system to be reset */
+ while (1)
+ ;
+}
+
+static void avr_power_off_system(void)
+{
+ avr_halt_system(AVR_PWRCTL_PWROFF);
+}
+
+static void avr_reset_system(char *cmd)
+{
+ avr_halt_system(AVR_PWRCTL_RESET);
+}
+
+static int avr_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ avr_i2c_client = client;
+ ppc_md.restart = avr_reset_system;
+ ppc_md.power_off = avr_power_off_system;
+ return 0;
+}
+
+static const struct i2c_device_id avr_id[] = {
+ { "akebono-avr", 0 },
+ { }
+};
+
+static struct i2c_driver avr_driver = {
+ .driver = {
+ .name = "akebono-avr",
+ },
+ .probe = avr_probe,
+ .id_table = avr_id,
+};
+
static int __init ppc47x_device_probe(void)
{
+ i2c_add_driver(&avr_driver);
of_platform_bus_probe(NULL, ppc47x_of_bus, NULL);
return 0;
}
machine_device_initcall(ppc47x, ppc47x_device_probe);
-/* We can have either UICs or MPICs */
static void __init ppc47x_init_irq(void)
{
struct device_node *np;
@@ -163,37 +219,30 @@ static void __init ppc47x_setup_arch(void)
ppc47x_smp_init();
}
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init ppc47x_probe(void)
-{
- unsigned long root = of_get_flat_dt_root();
-
- if (!of_flat_dt_is_compatible(root, "ibm,currituck"))
- return 0;
-
- return 1;
-}
-
static int board_rev = -1;
static int __init ppc47x_get_board_rev(void)
{
- u8 fpga_reg0;
- void *fpga;
- struct device_node *np;
+ int reg;
+ u8 *fpga;
+ struct device_node *np = NULL;
+
+ if (of_machine_is_compatible("ibm,currituck")) {
+ np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga");
+ reg = 0;
+ } else if (of_machine_is_compatible("ibm,akebono")) {
+ np = of_find_compatible_node(NULL, NULL, "ibm,akebono-fpga");
+ reg = 2;
+ }
- np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga");
if (!np)
goto fail;
- fpga = of_iomap(np, 0);
+ fpga = (u8 *) of_iomap(np, 0);
of_node_put(np);
if (!fpga)
goto fail;
- fpga_reg0 = ioread8(fpga);
- board_rev = fpga_reg0 & 0x03;
+ board_rev = ioread8(fpga + reg) & 0x03;
pr_info("%s: Found board revision %d\n", __func__, board_rev);
iounmap(fpga);
return 0;
@@ -221,13 +270,30 @@ static void ppc47x_pci_irq_fixup(struct pci_dev *dev)
}
}
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init ppc47x_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "ibm,akebono"))
+ return 1;
+
+ if (of_flat_dt_is_compatible(root, "ibm,currituck")) {
+ ppc_md.pci_irq_fixup = ppc47x_pci_irq_fixup;
+ return 1;
+ }
+
+ return 0;
+}
+
define_machine(ppc47x) {
.name = "PowerPC 47x",
.probe = ppc47x_probe,
.progress = udbg_progress,
.init_IRQ = ppc47x_init_irq,
.setup_arch = ppc47x_setup_arch,
- .pci_irq_fixup = ppc47x_pci_irq_fixup,
.restart = ppc4xx_reset_system,
.calibrate_decr = generic_calibrate_decr,
};
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index dba5e4d..771a0ba 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -1440,7 +1440,8 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops;
#endif
#ifdef CONFIG_476
- if (of_device_is_compatible(np, "ibm,plb-pciex-476fpe"))
+ if (of_device_is_compatible(np, "ibm,plb-pciex-476fpe")
+ || of_device_is_compatible(np, "ibm,plb-pciex-476gtr"))
ppc4xx_pciex_hwops = &ppc476_pcie_hwops;
#endif
if (ppc4xx_pciex_hwops == NULL) {
@@ -1751,7 +1752,10 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT
| DCRO_PEGPL_OMRxMSKL_VAL);
- else if (of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe"))
+ else if (of_device_is_compatible(
+ port->node, "ibm,plb-pciex-476fpe") ||
+ of_device_is_compatible(
+ port->node, "ibm,plb-pciex-476gtr"))
dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
sa | DCRO_PEGPL_476_OMR1MSKL_UOT
| DCRO_PEGPL_OMRxMSKL_VAL);
@@ -1881,7 +1885,10 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
sa |= PCI_BASE_ADDRESS_MEM_PREFETCH;
if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx") ||
- of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe"))
+ of_device_is_compatible(
+ port->node, "ibm,plb-pciex-476fpe") ||
+ of_device_is_compatible(
+ port->node, "ibm,plb-pciex-476gtr"))
sa |= PCI_BASE_ADDRESS_MEM_TYPE_64;
out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
--
1.7.10.4
^ 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