Re: [PATCH v5 7/8] iommu/amd: Don't update domain info to dte entry at iommu init stage
On 09/21/16 at 06:26pm, Baoquan He wrote: > On 09/20/16 at 02:50pm, Joerg Roedel wrote: > > On Thu, Sep 15, 2016 at 11:03:25PM +0800, Baoquan He wrote: > > > AMD iommu creates protection domain and assign each device to it during > > > iommu driver initialization stage. This happened just after system pci > > > bus scanning stage, and much earlier than device driver init stage. So > > > at this time if in kdump kernel the domain info, especially pte_root, > > > can't be updated to dte entry. We should wait until device driver init > > > stage. > > > > > > Signed-off-by: Baoquan He > > > --- > > > drivers/iommu/amd_iommu.c | 18 ++ > > > 1 file changed, 18 insertions(+) > > > > > > diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c > > > index fcb69ff..6c37300 100644 > > > --- a/drivers/iommu/amd_iommu.c > > > +++ b/drivers/iommu/amd_iommu.c > > > @@ -137,6 +137,7 @@ struct iommu_dev_data { > > > bool pri_tlp; /* PASID TLB required for > > >PPR completions */ > > > u32 errata; /* Bitmap for errata to apply */ > > > + bool domain_updated; > > > }; > > > > > > /* > > > @@ -1708,6 +1709,15 @@ static void set_dte_entry(u16 devid, struct > > > protection_domain *domain, bool ats) > > > { > > > u64 pte_root = 0; > > > u64 flags = 0; > > > + struct iommu_dev_data *dev_data; > > > + struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; > > > + > > > + dev_data = find_dev_data(devid); > > > +if (!dev_data) > > > +return; > > > + > > > + if (translation_pre_enabled(iommu) && !dev_data->domain_updated) > > > + return; > > > > > > if (domain->mode != PAGE_MODE_NONE) > > > pte_root = virt_to_phys(domain->pt_root); > > > @@ -1756,6 +1766,14 @@ static void set_dte_entry(u16 devid, struct > > > protection_domain *domain, bool ats) > > > > > > static void clear_dte_entry(u16 devid) > > > { > > > + struct iommu_dev_data *dev_data; > > > + struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; > > > + > > > + dev_data = find_dev_data(devid); > > > +if (!dev_data) > > > +return; > > > + if (translation_pre_enabled(iommu) && !dev_data->domain_updated) > > > + return; > > > > This should be moved to do_attach/do_detach. There you also already have > > the dev_data you need here. > > For amd-vi v1, checking in do_attach/do_detach is enough. But for v2 > amd_iommu_domain_direct_map and amd_iommu_domain_enable_v2 also call it Here I means amd_iommu_domain_direct_map and amd_iommu_domain_enable_v2 will call set_dte_entry to change pte_root setting. > to install pte_root into dev table. So finally, I move them into these > two lowest level functions to prevent any pte_root changing during iommu > init stage. It involves the least code change. > > > > > > /* remove entry from the device table seen by the hardware */ > > > amd_iommu_dev_table[devid].data[0] = DTE_FLAG_V | DTE_FLAG_TV; > > > amd_iommu_dev_table[devid].data[1] &= DTE_FLAG_MASK; > > > -- > > > 2.5.5 > > > ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v5 8/8] iommu/amd: Update domain into to dte entry during device driver init
On 09/20/16 at 02:53pm, Joerg Roedel wrote: > On Thu, Sep 15, 2016 at 11:03:26PM +0800, Baoquan He wrote: > > All devices are supposed to reset themselves at device driver initialization > > stage. At this time if in kdump kernel those on-flight DMA will be stopped > > because of device reset. It's best time to update the protection domain > > info, > > especially pte_root, to dte entry which the device relates to. > > > > Signed-off-by: Baoquan He > > --- > > drivers/iommu/amd_iommu.c | 21 + > > 1 file changed, 21 insertions(+) > > > > diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c > > index 6c37300..00b64ee 100644 > > --- a/drivers/iommu/amd_iommu.c > > +++ b/drivers/iommu/amd_iommu.c > > @@ -2310,6 +2310,10 @@ static dma_addr_t __map_single(struct device *dev, > > unsigned int pages; > > int prot = 0; > > int i; > > + struct iommu_dev_data *dev_data = get_dev_data(dev); > > + struct protection_domain *domain = get_domain(dev); > > + u16 alias = amd_iommu_alias_table[dev_data->devid]; > > + struct amd_iommu *iommu = amd_iommu_rlookup_table[dev_data->devid]; > > > > pages = iommu_num_pages(paddr, size, PAGE_SIZE); > > paddr &= PAGE_MASK; > > @@ -2319,6 +2323,13 @@ static dma_addr_t __map_single(struct device *dev, > > goto out; > > > > prot = dir2prot(direction); > > + if (translation_pre_enabled(iommu) && !dev_data->domain_updated) { > > + dev_data->domain_updated = true; > > + set_dte_entry(dev_data->devid, domain, > > dev_data->ats.enabled); > > + if (alias != dev_data->devid) > > + set_dte_entry(alias, domain, dev_data->ats.enabled); > > + device_flush_dte(dev_data); > > + } > > Hmm, have you tried hooking this into the set_dma_mask call-back? Every > driver should call it for its device, so that should be a better > indicator to now map a new domain. Very earlier you mentioned this, and I tried, but failed. I guess that is because of the bnx2 NIC resetting problem. Let me try it again. In theory it should be better. Just sometime people probably don't call set_dma_mask explicitly, then default dma mask is used. This could be seen in those simple device. For those complicated device like sata disk and ethernet NIC, set_dma_mask should be called. So I would like to try and use set_dma_mask. Thanks for your great suggestion. Thanks Baoquan ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v5 7/8] iommu/amd: Don't update domain info to dte entry at iommu init stage
On 09/20/16 at 02:50pm, Joerg Roedel wrote: > On Thu, Sep 15, 2016 at 11:03:25PM +0800, Baoquan He wrote: > > AMD iommu creates protection domain and assign each device to it during > > iommu driver initialization stage. This happened just after system pci > > bus scanning stage, and much earlier than device driver init stage. So > > at this time if in kdump kernel the domain info, especially pte_root, > > can't be updated to dte entry. We should wait until device driver init > > stage. > > > > Signed-off-by: Baoquan He > > --- > > drivers/iommu/amd_iommu.c | 18 ++ > > 1 file changed, 18 insertions(+) > > > > diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c > > index fcb69ff..6c37300 100644 > > --- a/drivers/iommu/amd_iommu.c > > +++ b/drivers/iommu/amd_iommu.c > > @@ -137,6 +137,7 @@ struct iommu_dev_data { > > bool pri_tlp; /* PASID TLB required for > > PPR completions */ > > u32 errata; /* Bitmap for errata to apply */ > > + bool domain_updated; > > }; > > > > /* > > @@ -1708,6 +1709,15 @@ static void set_dte_entry(u16 devid, struct > > protection_domain *domain, bool ats) > > { > > u64 pte_root = 0; > > u64 flags = 0; > > + struct iommu_dev_data *dev_data; > > + struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; > > + > > + dev_data = find_dev_data(devid); > > +if (!dev_data) > > +return; > > + > > + if (translation_pre_enabled(iommu) && !dev_data->domain_updated) > > + return; > > > > if (domain->mode != PAGE_MODE_NONE) > > pte_root = virt_to_phys(domain->pt_root); > > @@ -1756,6 +1766,14 @@ static void set_dte_entry(u16 devid, struct > > protection_domain *domain, bool ats) > > > > static void clear_dte_entry(u16 devid) > > { > > + struct iommu_dev_data *dev_data; > > + struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; > > + > > + dev_data = find_dev_data(devid); > > +if (!dev_data) > > +return; > > + if (translation_pre_enabled(iommu) && !dev_data->domain_updated) > > + return; > > This should be moved to do_attach/do_detach. There you also already have > the dev_data you need here. For amd-vi v1, checking in do_attach/do_detach is enough. But for v2 amd_iommu_domain_direct_map and amd_iommu_domain_enable_v2 also call it to install pte_root into dev table. So finally, I move them into these two lowest level functions to prevent any pte_root changing during iommu init stage. It involves the least code change. > > > /* remove entry from the device table seen by the hardware */ > > amd_iommu_dev_table[devid].data[0] = DTE_FLAG_V | DTE_FLAG_TV; > > amd_iommu_dev_table[devid].data[1] &= DTE_FLAG_MASK; > > -- > > 2.5.5 > > ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v5 6/8] iommu/amd: Do not re-enable dev table entries in kdump
On 09/20/16 at 02:42pm, Joerg Roedel wrote: > On Thu, Sep 15, 2016 at 11:03:24PM +0800, Baoquan He wrote: > > This enabling should have been done in normal kernel. It's unnecessary > > to enable it again in kdump kernel. > > > > And clean up the function comments of init_device_table_dma. > > Well, no. We don't want to make any assumptions on what the previous > kernel did and what it did not. The init_device_table_dma() code should > run anyway. Yes, right. I forget people could set amd_iommu=off in 1st kernel, but remove it in kdump kernel. Will change and merge the comment clean up into another patch. > ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v5 5/8] iommu/amd: copy old trans table from old kernel
On 09/20/16 at 02:40pm, Joerg Roedel wrote: > On Thu, Sep 15, 2016 at 11:03:23PM +0800, Baoquan He wrote: > > Here several things need be done: > > 1) If iommu is pre-enabled in a normal kernel, just disable it and print > >warning. > > 2) If failed to copy dev table of old kernel, continue to proceed as > >it does in normal kernel. > > 3) Re-enable event/cmd buffer and install the new DTE table to reg. > > 4) Flush all caches > > > > Signed-off-by: Baoquan He > > --- > > drivers/iommu/amd_iommu_init.c | 44 > > +++--- > > 1 file changed, 41 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c > > index ce49641..47a8fc9 100644 > > --- a/drivers/iommu/amd_iommu_init.c > > +++ b/drivers/iommu/amd_iommu_init.c > > @@ -34,7 +34,7 @@ > > #include > > #include > > #include > > - > > +#include > > Please keep that empty line, it is there for readability. Thanks, will change. > > > #include "amd_iommu_proto.h" > > #include "amd_iommu_types.h" > > #include "irq_remapping.h" > > @@ -1344,6 +1344,12 @@ static int __init init_iommu_one(struct amd_iommu > > *iommu, struct ivhd_header *h) > > iommu->int_enabled = false; > > > > init_translation_status(iommu); > > + if (translation_pre_enabled(iommu) && !is_kdump_kernel()) { > > + iommu_disable(iommu); > > + clear_translation_pre_enabled(iommu); > > + pr_warn("Translation was enabled for IOMMU:%d but we are not in > > kdump mode\n", > > + iommu->index); > > + } > > > > if (translation_pre_enabled(iommu)) > > pr_warn("Translation is already enabled - trying to copy > > translation structures\n"); > > @@ -1946,9 +1952,41 @@ static void early_enable_iommu(struct amd_iommu > > *iommu) > > static void early_enable_iommus(void) > > { > > struct amd_iommu *iommu; > > + bool is_pre_enabled=false; > > > > - for_each_iommu(iommu) > > - early_enable_iommu(iommu); > > + for_each_iommu(iommu) { > > + if ( translation_pre_enabled(iommu) ) { > > Coding style, too many spaces. There is more of that below. Will change. > > > + is_pre_enabled = true; > > + break; > > + } > > + } > > + > > + if ( !is_pre_enabled) { > > + for_each_iommu(iommu) > > + early_enable_iommu(iommu); > > + } else { > > + if (copy_dev_tables()) { > > + pr_err("Failed to copy DEV table from previous > > kernel.\n"); > > + /* > > +* If failed to copy dev tables from old kernel, > > continue to proceed > > +* as it does in normal kernel. > > +*/ > > + for_each_iommu(iommu) { > > + clear_translation_pre_enabled(iommu); > > + early_enable_iommu(iommu); > > + } > > + } else { > > + pr_info("Copied DEV table from previous kernel.\n"); > > + for_each_iommu(iommu) { > > + iommu_feature_disable(iommu, CONTROL_CMDBUF_EN); > > + iommu_feature_disable(iommu, > > CONTROL_EVT_LOG_EN); > > Could you move that into new helpers (iommu_disable_command_buffer...)? Yes, sure, will do. > > > + iommu_enable_command_buffer(iommu); > > + iommu_enable_event_buffer(iommu); > > + iommu_set_device_table(iommu); > > + iommu_flush_all_caches(iommu); > > + } > > + } > > + } > > } > > > > static void enable_iommus_v2(void) > > -- > > 2.5.5 > > ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v5 4/8] iommu/amd: Add function copy_dev_tables
Hi Joerg, Thanks for your reviewing and great suggestion! On 09/20/16 at 01:58pm, Joerg Roedel wrote: > Hi Baoquan, > > On Thu, Sep 15, 2016 at 11:03:22PM +0800, Baoquan He wrote: > > +static int copy_dev_tables(void) > > +{ > > + u64 entry; > > + u32 lo, hi, devid; > > + phys_addr_t old_devtb_phys; > > + struct dev_table_entry *old_devtb = NULL; > > + u16 dom_id, dte_v; > > + struct amd_iommu *iommu; > > + static int copied; > > Please order this by line-length, longer lines first. Will do. > > > +for_each_iommu(iommu) { > > + if (!translation_pre_enabled(iommu)) { > > + pr_err("IOMMU:%d is not pre-enabled!/n", iommu->index); > > + return -1; > > + } > > + > > + if (copied) > > + continue; > > + > > +lo = readl(iommu->mmio_base + MMIO_DEV_TABLE_OFFSET); > > +hi = readl(iommu->mmio_base + MMIO_DEV_TABLE_OFFSET + 4); > > +entry = (((u64) hi) << 32) + lo; > > +old_devtb_phys = entry & PAGE_MASK; > > +old_devtb = memremap(old_devtb_phys, dev_table_size, > > MEMREMAP_WB); > > + if (!old_devtb) > > + return -1; > > +for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) { > > +amd_iommu_dev_table[devid] = old_devtb[devid]; > > +dom_id = amd_iommu_dev_table[devid].data[1] & > > DEV_DOMID_MASK; > > + dte_v = amd_iommu_dev_table[devid].data[0] & DTE_FLAG_V; > > + if (!dte_v || !dom_id) > > + continue; > > +__set_bit(dom_id, amd_iommu_pd_alloc_bitmap); > > +} > > + memunmap(old_devtb); > > + copied = 1; > > +} > > This loop need more refinement and sanity checking code. I suggest using > two loops and do the sanity checking in the first one. The sanity checks > should do: > > * Check whether all IOMMUs actually use the same device table > with the same size > > * Verify that the size of the old device table is the expected > size. Will do. > > * Also sanity check the irq-remapping information and remapping > table sizes. Will do. Since this need those irq DTE_IRQ_ MACRO which is defined in amd_iommu.c , I plan to move them into amd_iommu_types.h, and then do irq-remapping. These can be made in another patch. > > If any of these checks fail, just bail out of copying. > > What is further needed it some more selection on what is copied from the > old kernel. There is no need to copy all the GCR3 root-pointer > information. If a device is set up with guest translations (DTE.GV=1), > then don't copy that information but move the device over to an empty > guest-cr3 table and handle the faults in the PPR log (which should just > answer them with INVALID). After all these PPR faults are recoverable > for the device and we should not allow the device to change old-kernels > data when we don't have to. The current fix is simplest and cleanest. Because the on-flight DMAs continue transferring data since system crash, including guest translations, we may not need to care about it and just let it continue flying a little more time until device is reset. Since you have suggested, I will try to make another patch for this issue, we can see the effect. Thanks Baoquan ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [v12, 7/8] base: soc: introduce soc_device_match() interface
On 2016-09-21 09:56, Alexander Shiyan wrote: >> Среда, 21 сентября 2016, 9:57 +03:00 от Yangbo Lu : >> >> From: Arnd Bergmann < a...@arndb.de > >> >> We keep running into cases where device drivers want to know the exact >> version of the a SoC they are currently running on. In the past, this has >> usually been done through a vendor specific API that can be called by a >> driver, or by directly accessing some kind of version register that is >> not part of the device itself but that belongs to a global register area >> of the chip. > ... >> +const struct soc_device_attribute *soc_device_match( >> +const struct soc_device_attribute *matches) >> +{ >> +int ret = 0; >> + >> +if (!matches) >> +return NULL; >> + >> +while (!ret) { >> +if (!(matches->machine || matches->family || >> + matches->revision || matches->soc_id)) >> +break; >> +ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, >> + soc_device_match_one); >> +if (!ret) >> +matches++; > > So, what happen if next "matches" (after increment) will be NULL? A crash? > I think you should use while(matches) at the start of this procedure. *arrgh* *If* matches wrap, you indeed have *big* problems. *Elsewhere* Hint: Please read the review comments on the previous version of this series [1] before commenting further. Cheers, Peter [1] https://www.mail-archive.com/netdev@vger.kernel.org/msg126617.html ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [v12, 7/8] base: soc: introduce soc_device_match() interface
>Среда, 21 сентября 2016, 9:57 +03:00 от Yangbo Lu : > >From: Arnd Bergmann < a...@arndb.de > > >We keep running into cases where device drivers want to know the exact >version of the a SoC they are currently running on. In the past, this has >usually been done through a vendor specific API that can be called by a >driver, or by directly accessing some kind of version register that is >not part of the device itself but that belongs to a global register area >of the chip. ... >+const struct soc_device_attribute *soc_device_match( >+const struct soc_device_attribute *matches) >+{ >+int ret = 0; >+ >+if (!matches) >+return NULL; >+ >+while (!ret) { >+if (!(matches->machine || matches->family || >+ matches->revision || matches->soc_id)) >+break; >+ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, >+ soc_device_match_one); >+if (!ret) >+matches++; So, what happen if next "matches" (after increment) will be NULL? I think you should use while(matches) at the start of this procedure. --- ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v12, 6/8] MAINTAINERS: add entry for Freescale SoC drivers
Add maintainer entry for Freescale SoC drivers including the QE library and the GUTS driver now. Also add maintainer for QE library. Signed-off-by: Yangbo Lu Acked-by: Scott Wood Acked-by: Qiang Zhao --- Changes for v8: - Added this patch Changes for v9: - Added linux-arm mail list - Removed GUTS driver entry Changes for v10: - Changed 'DRIVER' to 'DRIVERS' - Added 'Acked-by' of Scott and Qiang Changes for v11: - None Changes for v12: - None --- MAINTAINERS | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 644ff65..33d3683 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4971,9 +4971,18 @@ F: drivers/net/ethernet/freescale/fec_ptp.c F: drivers/net/ethernet/freescale/fec.h F: Documentation/devicetree/bindings/net/fsl-fec.txt +FREESCALE SOC DRIVERS +M: Scott Wood +L: linuxppc-...@lists.ozlabs.org +L: linux-arm-ker...@lists.infradead.org +S: Maintained +F: drivers/soc/fsl/ +F: include/linux/fsl/ + FREESCALE QUICC ENGINE LIBRARY +M: Qiang Zhao L: linuxppc-...@lists.ozlabs.org -S: Orphan +S: Maintained F: drivers/soc/fsl/qe/ F: include/soc/fsl/*qe*.h F: include/soc/fsl/*ucc*.h -- 2.1.0.27.g96db324 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v12, 7/8] base: soc: introduce soc_device_match() interface
From: Arnd Bergmann We keep running into cases where device drivers want to know the exact version of the a SoC they are currently running on. In the past, this has usually been done through a vendor specific API that can be called by a driver, or by directly accessing some kind of version register that is not part of the device itself but that belongs to a global register area of the chip. Common reasons for doing this include: - A machine is not using devicetree or similar for passing data about on-chip devices, but just announces their presence using boot-time platform devices, and the machine code itself does not care about the revision. - There is existing firmware or boot loaders with existing DT binaries with generic compatible strings that do not identify the particular revision of each device, but the driver knows which SoC revisions include which part. - A prerelease version of a chip has some quirks and we are using the same version of the bootloader and the DT blob on both the prerelease and the final version. An update of the DT binding seems inappropriate because that would involve maintaining multiple copies of the dts and/or bootloader. This patch introduces the soc_device_match() interface that is meant to work like of_match_node() but instead of identifying the version of a device, it identifies the SoC itself using a vendor-agnostic interface. Unlike of_match_node(), we do not do an exact string compare but instead use glob_match() to allow wildcards in strings. Signed-off-by: Arnd Bergmann Signed-off-by: Yangbo Lu --- Changes for v11: - Added this patch for soc match Changes for v12: - Corrected the author - Rewrited soc_device_match with while loop --- drivers/base/Kconfig| 1 + drivers/base/soc.c | 66 + include/linux/sys_soc.h | 3 +++ 3 files changed, 70 insertions(+) diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 98504ec..f1591ad2 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -225,6 +225,7 @@ config GENERIC_CPU_AUTOPROBE config SOC_BUS bool + select GLOB source "drivers/base/regmap/Kconfig" diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 75b98aa..d2fd1ad 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -14,6 +14,7 @@ #include #include #include +#include static DEFINE_IDA(soc_ida); @@ -168,3 +169,68 @@ static void __exit soc_bus_unregister(void) bus_unregister(&soc_bus_type); } module_exit(soc_bus_unregister); + +static int soc_device_match_one(struct device *dev, void *arg) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + const struct soc_device_attribute *match = arg; + + if (match->machine && + !glob_match(match->machine, soc_dev->attr->machine)) + return 0; + + if (match->family && + !glob_match(match->family, soc_dev->attr->family)) + return 0; + + if (match->revision && + !glob_match(match->revision, soc_dev->attr->revision)) + return 0; + + if (match->soc_id && + !glob_match(match->soc_id, soc_dev->attr->soc_id)) + return 0; + + return 1; +} + +/* + * soc_device_match - identify the SoC in the machine + * @matches: zero-terminated array of possible matches + * + * returns the first matching entry of the argument array, or NULL + * if none of them match. + * + * This function is meant as a helper in place of of_match_node() + * in cases where either no device tree is available or the information + * in a device node is insufficient to identify a particular variant + * by its compatible strings or other properties. For new devices, + * the DT binding should always provide unique compatible strings + * that allow the use of of_match_node() instead. + * + * The calling function can use the .data entry of the + * soc_device_attribute to pass a structure or function pointer for + * each entry. + */ +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches) +{ + int ret = 0; + + if (!matches) + return NULL; + + while (!ret) { + if (!(matches->machine || matches->family || + matches->revision || matches->soc_id)) + break; + ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, + soc_device_match_one); + if (!ret) + matches++; + else + return matches; + } + return NULL; +} +EXPORT_SYMBOL_GPL(soc_device_match); diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h index 2739ccb..9f5eb06 100644 --- a/include/linux/sys_soc.h +++ b/include/linux/sys_soc.h @@ -13,6 +13,7 @@ struct soc_device_attribute { const char *family;
[v12, 8/8] mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0
The eSDHC of T4240-R1.0-R2.0 has incorrect vender version and spec version. Acturally the right version numbers should be VVN=0x13 and SVN = 0x1. This patch adds the GUTS driver support for eSDHC driver to match SoC. And fix host version to avoid that incorrect version numbers break down the ADMA data transfer. Signed-off-by: Yangbo Lu Acked-by: Ulf Hansson Acked-by: Scott Wood --- Changes for v2: - Got SVR through iomap instead of dts Changes for v3: - Managed GUTS through syscon instead of iomap in eSDHC driver Changes for v4: - Got SVR by GUTS driver instead of SYSCON Changes for v5: - Changed to get SVR through API fsl_guts_get_svr() - Combined patch 4, patch 5 and patch 6 into one Changes for v6: - Added 'Acked-by: Ulf Hansson' Changes for v7: - None Changes for v8: - Added 'Acked-by: Scott Wood' Changes for v9: - None Changes for v10: - None Changes for v11: - Changed to use soc_device_match Changes for v12: - Matched soc through .family field instead of .soc_id --- drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-of-esdhc.c | 20 2 files changed, 21 insertions(+) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 5274f50..a1135a9 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -144,6 +144,7 @@ config MMC_SDHCI_OF_ESDHC depends on MMC_SDHCI_PLTFM depends on PPC || ARCH_MXC || ARCH_LAYERSCAPE select MMC_SDHCI_IO_ACCESSORS + select FSL_GUTS help This selects the Freescale eSDHC controller support. diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index fb71c86..57bdb9e 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "sdhci-pltfm.h" #include "sdhci-esdhc.h" @@ -28,6 +29,7 @@ struct sdhci_esdhc { u8 vendor_ver; u8 spec_ver; + bool quirk_incorrect_hostver; }; /** @@ -73,6 +75,8 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host, static u16 esdhc_readw_fixup(struct sdhci_host *host, int spec_reg, u32 value) { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); u16 ret; int shift = (spec_reg & 0x2) * 8; @@ -80,6 +84,12 @@ static u16 esdhc_readw_fixup(struct sdhci_host *host, ret = value & 0x; else ret = (value >> shift) & 0x; + /* Workaround for T4240-R1.0-R2.0 eSDHC which has incorrect +* vendor version and spec version information. +*/ + if ((spec_reg == SDHCI_HOST_VERSION) && + (esdhc->quirk_incorrect_hostver)) + ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200; return ret; } @@ -558,6 +568,12 @@ static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { .ops = &sdhci_esdhc_le_ops, }; +static struct soc_device_attribute soc_incorrect_hostver[] = { + { .family = "QorIQ T4240", .revision = "1.0", }, + { .family = "QorIQ T4240", .revision = "2.0", }, + { }, +}; + static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host; @@ -571,6 +587,10 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK; + if (soc_device_match(soc_incorrect_hostver)) + esdhc->quirk_incorrect_hostver = true; + else + esdhc->quirk_incorrect_hostver = false; } static int sdhci_esdhc_probe(struct platform_device *pdev) -- 2.1.0.27.g96db324 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v12, 5/8] soc: fsl: add GUTS driver for QorIQ platforms
The global utilities block controls power management, I/O device enabling, power-onreset(POR) configuration monitoring, alternate function selection for multiplexed signals,and clock control. This patch adds a driver to manage and access global utilities block. Initially only reading SVR and registering soc device are supported. Other guts accesses, such as reading RCW, should eventually be moved into this driver as well. Signed-off-by: Yangbo Lu --- Changes for v4: - Added this patch Changes for v5: - Modified copyright info - Changed MODULE_LICENSE to GPL - Changed EXPORT_SYMBOL_GPL to EXPORT_SYMBOL - Made FSL_GUTS user-invisible - Added a complete compatible list for GUTS - Stored guts info in file-scope variable - Added mfspr() getting SVR - Redefined GUTS APIs - Called fsl_guts_init rather than using platform driver - Removed useless parentheses - Removed useless 'extern' key words Changes for v6: - Made guts thread safe in fsl_guts_init Changes for v7: - Removed 'ifdef' for function declaration in guts.h Changes for v8: - Fixes lines longer than 80 characters checkpatch issue - Added 'Acked-by: Scott Wood' Changes for v9: - None Changes for v10: - None Changes for v11: - Changed to platform driver Changes for v12: - Removed "signed-off-by: Scott" - Defined fsl_soc_die_attr struct array instead of soc_device_attribute - Re-designed soc_device_attribute for QorIQ SoC - Other minor fixes --- drivers/soc/Kconfig | 2 +- drivers/soc/fsl/Kconfig | 19 drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/guts.c | 257 +++ include/linux/fsl/guts.h | 125 ++- 5 files changed, 355 insertions(+), 49 deletions(-) create mode 100644 drivers/soc/fsl/Kconfig create mode 100644 drivers/soc/fsl/guts.c diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index fe42a2f..f31bceb 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,7 +1,7 @@ menu "SOC (System On Chip) specific Drivers" source "drivers/soc/bcm/Kconfig" -source "drivers/soc/fsl/qe/Kconfig" +source "drivers/soc/fsl/Kconfig" source "drivers/soc/mediatek/Kconfig" source "drivers/soc/qcom/Kconfig" source "drivers/soc/rockchip/Kconfig" diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig new file mode 100644 index 000..b99764c --- /dev/null +++ b/drivers/soc/fsl/Kconfig @@ -0,0 +1,19 @@ +# +# Freescale SOC drivers +# + +source "drivers/soc/fsl/qe/Kconfig" + +config FSL_GUTS + bool "Freescale QorIQ GUTS driver" + select SOC_BUS + help + The global utilities block controls power management, I/O device + enabling, power-onreset(POR) configuration monitoring, alternate + function selection for multiplexed signals,and clock control. + This driver is to manage and access global utilities block. + Initially only reading SVR and registering soc device are supported. + Other guts accesses, such as reading RCW, should eventually be moved + into this driver as well. + + If you want GUTS driver support, you should say Y here. diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 203307f..02afb7f 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ +obj-$(CONFIG_FSL_GUTS) += guts.o diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c new file mode 100644 index 000..2a0e52c --- /dev/null +++ b/drivers/soc/fsl/guts.c @@ -0,0 +1,257 @@ +/* + * Freescale QorIQ Platforms GUTS Driver + * + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +struct guts { + struct ccsr_guts __iomem *regs; + bool little_endian; +}; + +struct fsl_soc_die_attr { + char*die; + u32 svr; + u32 mask; +}; + +static struct guts *guts; +static struct soc_device_attribute soc_dev_attr; +static struct soc_device *soc_dev; + + +/* SoC die attribute definition for QorIQ platform */ +static const struct fsl_soc_die_attr fsl_soc_die[] = { +#ifdef CONFIG_PPC + /* +* Power Architecture-based SoCs T Series +*/ + + /* Die: T4240, SoC: T4240/T4160/T4080 */ + { .die = "T4240", + .svr = 0x8240, + .mask = 0xfff0, + }, + /* Die: T1040, SoC: T1040/T1020/T1042/T1022 */ +
[v12, 4/8] powerpc/fsl: move mpc85xx.h to include/linux/fsl
Move mpc85xx.h to include/linux/fsl and rename it to svr.h as a common header file. This SVR numberspace is used on some ARM chips as well as PPC, and even to check for a PPC SVR multi-arch drivers would otherwise need to ifdef the header inclusion and all references to the SVR symbols. Signed-off-by: Yangbo Lu Acked-by: Wolfram Sang Acked-by: Stephen Boyd Acked-by: Joerg Roedel [scottwood: update description] Signed-off-by: Scott Wood --- Changes for v2: - None Changes for v3: - None Changes for v4: - None Changes for v5: - Changed to Move mpc85xx.h to include/linux/fsl/ - Adjusted '#include ' position in file Changes for v6: - None Changes for v7: - Added 'Acked-by: Wolfram Sang' for I2C part - Also applied to arch/powerpc/kernel/cpu_setup_fsl_booke.S Changes for v8: - Added 'Acked-by: Stephen Boyd' for clk part - Added 'Acked-by: Scott Wood' - Added 'Acked-by: Joerg Roedel' for iommu part Changes for v9: - None Changes for v10: - None Changes for v11: - Updated description by Scott Changes for v12: - None --- arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +- arch/powerpc/sysdev/fsl_pci.c | 2 +- drivers/clk/clk-qoriq.c | 3 +-- drivers/i2c/busses/i2c-mpc.c | 2 +- drivers/iommu/fsl_pamu.c | 3 +-- drivers/net/ethernet/freescale/gianfar.c | 2 +- arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h | 4 ++-- 7 files changed, 8 insertions(+), 10 deletions(-) rename arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h (97%) diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index 462aed9..2b0284e 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -13,13 +13,13 @@ * */ +#include #include #include #include #include #include #include -#include _GLOBAL(__e500_icache_setup) mfspr r0, SPRN_L1CSR1 diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 0ef9df4..0fd1895 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 58566a17..4b6c438 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -1149,8 +1150,6 @@ bad_args: } #ifdef CONFIG_PPC -#include - static const u32 a4510_svrs[] __initconst = { (SVR_P2040 << 8) | 0x10,/* P2040 1.0 */ (SVR_P2040 << 8) | 0x11,/* P2040 1.1 */ diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 48ecffe..600704c 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -27,9 +27,9 @@ #include #include #include +#include #include -#include #include #define DRV_NAME "mpc-i2c" diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c index a34355f..af8fb27 100644 --- a/drivers/iommu/fsl_pamu.c +++ b/drivers/iommu/fsl_pamu.c @@ -21,11 +21,10 @@ #include "fsl_pamu.h" #include +#include #include #include -#include - /* define indexes for each operation mapping scenario */ #define OMI_QMAN0x00 #define OMI_FMAN0x01 diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4b4f5bc..55be5ce 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -86,11 +86,11 @@ #include #include #include +#include #include #ifdef CONFIG_PPC #include -#include #endif #include #include diff --git a/arch/powerpc/include/asm/mpc85xx.h b/include/linux/fsl/svr.h similarity index 97% rename from arch/powerpc/include/asm/mpc85xx.h rename to include/linux/fsl/svr.h index 213f3a8..8d13836 100644 --- a/arch/powerpc/include/asm/mpc85xx.h +++ b/include/linux/fsl/svr.h @@ -9,8 +9,8 @@ * (at your option) any later version. */ -#ifndef __ASM_PPC_MPC85XX_H -#define __ASM_PPC_MPC85XX_H +#ifndef FSL_SVR_H +#define FSL_SVR_H #define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */ #define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/ -- 2.1.0.27.g96db324 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v12, 1/8] dt: bindings: update Freescale DCFG compatible
Update Freescale DCFG compatible with 'fsl,-dcfg' instead of 'fsl,ls1021a-dcfg' to include more chips such as ls1021a, ls1043a, and ls2080a. Signed-off-by: Yangbo Lu Acked-by: Rob Herring Signed-off-by: Scott Wood --- Changes for v8: - Added this patch Changes for v9: - Added a list for the possible compatibles Changes for v10: - None Changes for v11: - Added 'Acked-by: Rob Herring' - Updated commit message by Scott Changes for v12: - None --- Documentation/devicetree/bindings/arm/fsl.txt | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt index dbbc095..713c1ae 100644 --- a/Documentation/devicetree/bindings/arm/fsl.txt +++ b/Documentation/devicetree/bindings/arm/fsl.txt @@ -119,7 +119,11 @@ Freescale DCFG configuration and status for the device. Such as setting the secondary core start address and release the secondary core from holdoff and startup. Required properties: - - compatible: should be "fsl,ls1021a-dcfg" + - compatible: should be "fsl,-dcfg" +Possible compatibles: + "fsl,ls1021a-dcfg" + "fsl,ls1043a-dcfg" + "fsl,ls2080a-dcfg" - reg : should contain base address and length of DCFG memory-mapped registers Example: -- 2.1.0.27.g96db324 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v12, 0/8] Fix eSDHC host version register bug
This patchset is used to fix a host version register bug in the T4240-R1.0-R2.0 eSDHC controller. To match the SoC version and revision, 10 previous version patchsets had tried many methods but all of them were rejected by reviewers. Such as - dts compatible method - syscon method - ifdef PPC method - GUTS driver getting SVR method Anrd suggested a soc_device_match method in v10, and this is the only available method left now. This v11 patchset introduces the soc_device_match interface in soc driver. The first six patches of Yangbo are to add the GUTS driver. This is used to register a soc device which contain soc version and revision information. The other two patches introduce the soc_device_match method in soc driver and apply it on esdhc driver to fix this bug. Arnd Bergmann (1): base: soc: introduce soc_device_match() interface Yangbo Lu (7): dt: bindings: update Freescale DCFG compatible ARM64: dts: ls2080a: add device configuration node dt: bindings: move guts devicetree doc out of powerpc directory powerpc/fsl: move mpc85xx.h to include/linux/fsl soc: fsl: add GUTS driver for QorIQ platforms MAINTAINERS: add entry for Freescale SoC drivers mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0 Documentation/devicetree/bindings/arm/fsl.txt | 6 +- .../bindings/{powerpc => soc}/fsl/guts.txt | 3 + MAINTAINERS| 11 +- arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 6 + arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +- arch/powerpc/sysdev/fsl_pci.c | 2 +- drivers/base/Kconfig | 1 + drivers/base/soc.c | 66 ++ drivers/clk/clk-qoriq.c| 3 +- drivers/i2c/busses/i2c-mpc.c | 2 +- drivers/iommu/fsl_pamu.c | 3 +- drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-of-esdhc.c | 20 ++ drivers/net/ethernet/freescale/gianfar.c | 2 +- drivers/soc/Kconfig| 2 +- drivers/soc/fsl/Kconfig| 19 ++ drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/guts.c | 257 + include/linux/fsl/guts.h | 125 ++ .../asm/mpc85xx.h => include/linux/fsl/svr.h | 4 +- include/linux/sys_soc.h| 3 + 21 files changed, 478 insertions(+), 61 deletions(-) rename Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt (91%) create mode 100644 drivers/soc/fsl/Kconfig create mode 100644 drivers/soc/fsl/guts.c rename arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h (97%) -- 2.1.0.27.g96db324 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v12, 2/8] ARM64: dts: ls2080a: add device configuration node
Add the dts node for device configuration unit that provides general purpose configuration and status for the device. Signed-off-by: Yangbo Lu Acked-by: Scott Wood --- Changes for v5: - Added this patch Changes for v6: - None Changes for v7: - None Changes for v8: - Added 'Acked-by: Scott Wood' Changes for v9: - None Changes for v10: - None Changes for v11: - None Changes for v12: - None --- arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi index e3b6034..f231a14 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi @@ -215,6 +215,12 @@ clocks = <&sysclk>; }; + dcfg: dcfg@1e0 { + compatible = "fsl,ls2080a-dcfg", "syscon"; + reg = <0x0 0x1e0 0x0 0x1>; + little-endian; + }; + serial0: serial@21c0500 { compatible = "fsl,ns16550", "ns16550a"; reg = <0x0 0x21c0500 0x0 0x100>; -- 2.1.0.27.g96db324 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v12, 3/8] dt: bindings: move guts devicetree doc out of powerpc directory
Move guts devicetree doc to Documentation/devicetree/bindings/soc/fsl/ since it's used by not only PowerPC but also ARM. And add a specification for 'little-endian' property. Signed-off-by: Yangbo Lu Acked-by: Rob Herring Acked-by: Scott Wood --- Changes for v4: - Added this patch Changes for v5: - Modified the description for little-endian property Changes for v6: - None Changes for v7: - None Changes for v8: - Added 'Acked-by: Scott Wood' - Added 'Acked-by: Rob Herring' Changes for v9: - None Changes for v10: - None Changes for v11: - None Changes for v12: - None --- Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt | 3 +++ 1 file changed, 3 insertions(+) rename Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt (91%) diff --git a/Documentation/devicetree/bindings/powerpc/fsl/guts.txt b/Documentation/devicetree/bindings/soc/fsl/guts.txt similarity index 91% rename from Documentation/devicetree/bindings/powerpc/fsl/guts.txt rename to Documentation/devicetree/bindings/soc/fsl/guts.txt index b71b203..07adca9 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/guts.txt +++ b/Documentation/devicetree/bindings/soc/fsl/guts.txt @@ -25,6 +25,9 @@ Recommended properties: - fsl,liodn-bits : Indicates the number of defined bits in the LIODN registers, for those SOCs that have a PAMU device. + - little-endian : Indicates that the global utilities block is little + endian. The default is big endian. + Examples: global-utilities@e {/* global utilities block */ compatible = "fsl,mpc8548-guts"; -- 2.1.0.27.g96db324 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu