* [PATCH v2 1/8] PM / Domains: Make genpd state allocation dynamic
From: Lina Iyer @ 2016-10-10 15:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAPDyKFo1wFdNo3hR9WUZJ=sonKi4_sWb1PUFvPvyHeavbvqLvw@mail.gmail.com>
On Mon, Oct 10 2016 at 02:40 -0600, Ulf Hansson wrote:
>On 8 October 2016 at 00:36, Lina Iyer <lina.iyer@linaro.org> wrote:
>> Allow PM Domain states to be defined dynamically by the drivers. This
>> removes the limitation on the maximum number of states possible for a
>> domain.
>>
>> Cc: Axel Haslam <ahaslam+renesas@baylibre.com>
>> Suggested-by: Ulf Hansson <ulf.hansson@linaro.org>
>> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
>> ---
>> arch/arm/mach-imx/gpc.c | 17 ++++++++++-------
>> drivers/base/power/domain.c | 36 ++++++++++++++++++++++++------------
>> include/linux/pm_domain.h | 5 ++---
>> 3 files changed, 36 insertions(+), 22 deletions(-)
>>
>> diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
>> index 0df062d..57a410b 100644
>> --- a/arch/arm/mach-imx/gpc.c
>> +++ b/arch/arm/mach-imx/gpc.c
>> @@ -380,13 +380,6 @@ static struct pu_domain imx6q_pu_domain = {
>> .name = "PU",
>> .power_off = imx6q_pm_pu_power_off,
>> .power_on = imx6q_pm_pu_power_on,
>> - .states = {
>> - [0] = {
>> - .power_off_latency_ns = 25000,
>> - .power_on_latency_ns = 2000000,
>> - },
>> - },
>> - .state_count = 1,
>> },
>> };
>>
>> @@ -430,6 +423,16 @@ static int imx_gpc_genpd_init(struct device *dev, struct regulator *pu_reg)
>> if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS))
>> return 0;
>>
>> + imx6q_pu_domain.base.states = devm_kzalloc(dev,
>> + sizeof(*imx6q_pu_domain.base.states),
>> + GFP_KERNEL);
>> + if (!imx6q_pu_domain.base.states)
>> + return -ENOMEM;
>> +
>> + imx6q_pu_domain.base.states[0].power_off_latency_ns = 25000;
>> + imx6q_pu_domain.base.states[0].power_on_latency_ns = 2000000;
>> + imx6q_pu_domain.base.state_count = 1;
>> +
>> pm_genpd_init(&imx6q_pu_domain.base, NULL, false);
>> return of_genpd_add_provider_onecell(dev->of_node,
>> &imx_gpc_onecell_data);
>> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
>> index e023066..4e87170 100644
>> --- a/drivers/base/power/domain.c
>> +++ b/drivers/base/power/domain.c
>> @@ -1282,6 +1282,21 @@ out:
>> }
>> EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
>>
>> +static int genpd_set_default_power_state(struct generic_pm_domain *genpd)
>> +{
>> + struct genpd_power_state *state;
>> +
>> + state = kzalloc(sizeof(*state), GFP_KERNEL);
>> + if (!state)
>> + return -ENOMEM;
>> +
>> + genpd->states = state;
>> + genpd->state_count = 1;
>> + genpd->free = state;
>> +
>> + return 0;
>> +}
>> +
>> /**
>> * pm_genpd_init - Initialize a generic I/O PM domain object.
>> * @genpd: PM domain object to initialize.
>> @@ -1293,6 +1308,8 @@ EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
>> int pm_genpd_init(struct generic_pm_domain *genpd,
>> struct dev_power_governor *gov, bool is_off)
>> {
>> + int ret;
>> +
>> if (IS_ERR_OR_NULL(genpd))
>> return -EINVAL;
>>
>> @@ -1325,19 +1342,12 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
>> genpd->dev_ops.start = pm_clk_resume;
>> }
>>
>> - if (genpd->state_idx >= GENPD_MAX_NUM_STATES) {
>> - pr_warn("Initial state index out of bounds.\n");
>> - genpd->state_idx = GENPD_MAX_NUM_STATES - 1;
>> - }
>> -
>> - if (genpd->state_count > GENPD_MAX_NUM_STATES) {
>> - pr_warn("Limiting states to %d\n", GENPD_MAX_NUM_STATES);
>> - genpd->state_count = GENPD_MAX_NUM_STATES;
>> - }
>> -
>> /* Use only one "off" state if there were no states declared */
>> - if (genpd->state_count == 0)
>> - genpd->state_count = 1;
>> + if (genpd->state_count == 0) {
>> + ret = genpd_set_default_power_state(genpd);
>> + if (ret)
>> + return ret;
>> + }
>>
>> mutex_lock(&gpd_list_lock);
>> list_add(&genpd->gpd_list_node, &gpd_list);
>> @@ -1374,6 +1384,8 @@ static int genpd_remove(struct generic_pm_domain *genpd)
>> kfree(link);
>> }
>>
>> + kfree(genpd->free);
>> +
>
>To be safe, let's move this after cancel_work_sync() - as to prevent
>no accesses is made to ->states pointer after you have freed it.
>
OK
Thanks,
Lina
>> list_del(&genpd->gpd_list_node);
>> mutex_unlock(&genpd->lock);
>> cancel_work_sync(&genpd->power_off_work);
>> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
>> index a09fe5c..de1d8f3 100644
>> --- a/include/linux/pm_domain.h
>> +++ b/include/linux/pm_domain.h
>> @@ -19,8 +19,6 @@
>> /* Defines used for the flags field in the struct generic_pm_domain */
>> #define GENPD_FLAG_PM_CLK (1U << 0) /* PM domain uses PM clk */
>>
>> -#define GENPD_MAX_NUM_STATES 8 /* Number of possible low power states */
>> -
>> enum gpd_status {
>> GPD_STATE_ACTIVE = 0, /* PM domain is active */
>> GPD_STATE_POWER_OFF, /* PM domain is off */
>> @@ -70,9 +68,10 @@ struct generic_pm_domain {
>> void (*detach_dev)(struct generic_pm_domain *domain,
>> struct device *dev);
>> unsigned int flags; /* Bit field of configs for genpd */
>> - struct genpd_power_state states[GENPD_MAX_NUM_STATES];
>> + struct genpd_power_state *states;
>> unsigned int state_count; /* number of states */
>> unsigned int state_idx; /* state that genpd will go to when off */
>> + void *free; /* Free the state that was allocated for default */
>>
>> };
>>
>> --
>> 2.7.4
>>
>
>After the minor change suggested above, you may add my ack.
>
>Kind regards
>Uffe
^ permalink raw reply
* [PATCH v2 3/8] PM / Domains: Allow domain power states to be read from DT
From: Lina Iyer @ 2016-10-10 15:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAPDyKFo62XuwsoqqPyFa7FYMutd2ng-xt9f7aFh_2T6ab=vAZg@mail.gmail.com>
On Mon, Oct 10 2016 at 04:01 -0600, Ulf Hansson wrote:
>On 8 October 2016 at 00:36, Lina Iyer <lina.iyer@linaro.org> wrote:
>> This patch allows domains to define idle states in the DT. SoC's can
>> define domain idle states in DT using the "domain-idle-states" property
>> of the domain provider. Add API to read the idle states from DT that can
>> be set in the genpd object.
>>
>> This patch is based on the original patch by Marc Titinger.
>>
>> Signed-off-by: Marc Titinger <mtitinger+renesas@baylibre.com>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
>> ---
>> drivers/base/power/domain.c | 95 +++++++++++++++++++++++++++++++++++++++++++++
>> include/linux/pm_domain.h | 8 ++++
>> 2 files changed, 103 insertions(+)
>>
>> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
>> index 4e87170..4208b67 100644
>> --- a/drivers/base/power/domain.c
>> +++ b/drivers/base/power/domain.c
>> @@ -1917,6 +1917,101 @@ out:
>> return ret ? -EPROBE_DEFER : 0;
>> }
>> EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
>> +
>> +static const struct of_device_id idle_state_match[] = {
>> + { .compatible = "arm,idle-state", },
>> + { }
>> +};
>> +
>> +static int genpd_parse_state(struct genpd_power_state *genpd_state,
>> + struct device_node *state_node)
>> +{
>> + int err;
>> + u32 residency;
>> + u32 entry_latency, exit_latency;
>> + const struct of_device_id *match_id;
>> +
>> + match_id = of_match_node(idle_state_match, state_node);
>> + if (!match_id)
>> + return -EINVAL;
>> +
>> + err = of_property_read_u32(state_node, "entry-latency-us",
>> + &entry_latency);
>> + if (err) {
>> + pr_debug(" * %s missing entry-latency-us property\n",
>> + state_node->full_name);
>> + return -EINVAL;
>> + }
>> +
>> + err = of_property_read_u32(state_node, "exit-latency-us",
>> + &exit_latency);
>> + if (err) {
>> + pr_debug(" * %s missing exit-latency-us property\n",
>> + state_node->full_name);
>> + return -EINVAL;
>> + }
>> +
>> + err = of_property_read_u32(state_node, "min-residency-us", &residency);
>> + if (!err)
>> + genpd_state->residency_ns = 1000 * residency;
>> +
>> + genpd_state->power_on_latency_ns = 1000 * exit_latency;
>> + genpd_state->power_off_latency_ns = 1000 * entry_latency;
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + * of_genpd_parse_idle_states: Return array of idle states for the genpd.
>> + *
>> + * @dn: The genpd device node
>> + * @states: The pointer to which the state array will be saved.
>> + * @n: The count of elements in the array returned from this function.
>> + *
>> + * Returns the device states parsed from the OF node. The memory for the states
>> + * is allocated by this function and is the responsibility of the caller to
>> + * free the memory after use.
>> + */
>> +int of_genpd_parse_idle_states(struct device_node *dn,
>> + struct genpd_power_state **states, int *n)
>
>Instead of taking **states as a parameter, let's instead return it as
>a pointer for the allocated struct. In case of failures, let's return
>ERR_PTR().
>
Hmm.. I thought about it. There are 2 return values from this function.
If we return a pointer to the allocated memory, we still have to return
the size of it as an argument. I wasn't happy splitting the return
values in 2 different places.
>> +{
>> + struct genpd_power_state *st;
>> + struct device_node *np;
>> + int i = 0;
>> + int err, ret;
>> + int count;
>> + struct of_phandle_iterator it;
>> +
>> + count = of_count_phandle_with_args(dn, "domain-idle-states", NULL);
>
>If count is zero or an error, we should return an error code (ERR_PTR()). Right?
>
OK
>> +
>> + st = kcalloc(count, sizeof(*st), GFP_KERNEL);
>> + if (!st)
>> + return -ENOMEM;
>> +
>> + /* Loop over the phandles until all the requested entry is found */
>> + of_for_each_phandle(&it, err, dn, "domain-idle-states", NULL, 0) {
>> + np = of_node_get(it.node);
>
>I don't think you need to increment the usage count for the device
>node as that is already managed by of_for_each_phandle().
>
>It's only in the error case below, when it's needed.
>
Hmm.. Didn't realize that.. will fix.
>> + ret = genpd_parse_state(&st[i++], np);
>> + if (ret) {
>> + pr_err
>> + ("Parsing idle state node %s failed with err %d\n",
>> + np->full_name, ret);
>> + of_node_put(np);
>> + goto fail;
>
>The goto seems unnecessary. Why not deal with all error handling here
>and return the error code?
>
>> + }
>> + of_node_put(np);
>
>According the comment above, you should be able to remove this.
>
>> + }
>> +
>> + *n = count;
>> + *states = st;
>> +
>> + return 0;
>> +fail:
>> + kfree(st);
>> + return ret;
>> +}
>> +EXPORT_SYMBOL(of_genpd_parse_idle_states);
>
>Please use EXPORT_SYMBOL_GPL() instead.
>
Hmm.. OK
Thanks,
Lina
>> +
>> #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
>>
>>
>> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
>> index f4492eb..b489496 100644
>> --- a/include/linux/pm_domain.h
>> +++ b/include/linux/pm_domain.h
>> @@ -205,6 +205,8 @@ extern int of_genpd_add_device(struct of_phandle_args *args,
>> extern int of_genpd_add_subdomain(struct of_phandle_args *parent,
>> struct of_phandle_args *new_subdomain);
>> extern struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
>> +extern int of_genpd_parse_idle_states(struct device_node *dn,
>> + struct genpd_power_state **states, int *n);
>>
>> int genpd_dev_pm_attach(struct device *dev);
>> #else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
>> @@ -234,6 +236,12 @@ static inline int of_genpd_add_subdomain(struct of_phandle_args *parent,
>> return -ENODEV;
>> }
>>
>> +static inline int of_genpd_parse_idle_states(struct device_node *dn,
>> + struct genpd_power_state **states, int *n)
>> +{
>> + return -ENODEV;
>> +}
>> +
>> static inline int genpd_dev_pm_attach(struct device *dev)
>> {
>> return -ENODEV;
>> --
>> 2.7.4
>>
>
>Kind regards
>Uffe
^ permalink raw reply
* [PATCH v13 15/15] vfio/type1: Return the MSI geometry through VFIO_IOMMU_GET_INFO capability chains
From: Auger Eric @ 2016-10-10 15:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007143811.1fb3ebfe@t450s.home>
Hi Alex,
On 07/10/2016 22:38, Alex Williamson wrote:
> On Fri, 7 Oct 2016 19:10:27 +0200
> Auger Eric <eric.auger@redhat.com> wrote:
>
>> Hi Alex,
>>
>> On 06/10/2016 22:42, Alex Williamson wrote:
>>> On Thu, 6 Oct 2016 14:20:40 -0600
>>> Alex Williamson <alex.williamson@redhat.com> wrote:
>>>
>>>> On Thu, 6 Oct 2016 08:45:31 +0000
>>>> Eric Auger <eric.auger@redhat.com> wrote:
>>>>
>>>>> This patch allows the user-space to retrieve the MSI geometry. The
>>>>> implementation is based on capability chains, now also added to
>>>>> VFIO_IOMMU_GET_INFO.
>>>>>
>>>>> The returned info comprise:
>>>>> - whether the MSI IOVA are constrained to a reserved range (x86 case) and
>>>>> in the positive, the start/end of the aperture,
>>>>> - or whether the IOVA aperture need to be set by the userspace. In that
>>>>> case, the size and alignment of the IOVA window to be provided are
>>>>> returned.
>>>>>
>>>>> In case the userspace must provide the IOVA aperture, we currently report
>>>>> a size/alignment based on all the doorbells registered by the host kernel.
>>>>> This may exceed the actual needs.
>>>>>
>>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>>>
>>>>> ---
>>>>> v11 -> v11:
>>>>> - msi_doorbell_pages was renamed msi_doorbell_calc_pages
>>>>>
>>>>> v9 -> v10:
>>>>> - move cap_offset after iova_pgsizes
>>>>> - replace __u64 alignment by __u32 order
>>>>> - introduce __u32 flags in vfio_iommu_type1_info_cap_msi_geometry and
>>>>> fix alignment
>>>>> - call msi-doorbell API to compute the size/alignment
>>>>>
>>>>> v8 -> v9:
>>>>> - use iommu_msi_supported flag instead of programmable
>>>>> - replace IOMMU_INFO_REQUIRE_MSI_MAP flag by a more sophisticated
>>>>> capability chain, reporting the MSI geometry
>>>>>
>>>>> v7 -> v8:
>>>>> - use iommu_domain_msi_geometry
>>>>>
>>>>> v6 -> v7:
>>>>> - remove the computation of the number of IOVA pages to be provisionned.
>>>>> This number depends on the domain/group/device topology which can
>>>>> dynamically change. Let's rely instead rely on an arbitrary max depending
>>>>> on the system
>>>>>
>>>>> v4 -> v5:
>>>>> - move msi_info and ret declaration within the conditional code
>>>>>
>>>>> v3 -> v4:
>>>>> - replace former vfio_domains_require_msi_mapping by
>>>>> more complex computation of MSI mapping requirements, especially the
>>>>> number of pages to be provided by the user-space.
>>>>> - reword patch title
>>>>>
>>>>> RFC v1 -> v1:
>>>>> - derived from
>>>>> [RFC PATCH 3/6] vfio: Extend iommu-info to return MSIs automap state
>>>>> - renamed allow_msi_reconfig into require_msi_mapping
>>>>> - fixed VFIO_IOMMU_GET_INFO
>>>>> ---
>>>>> drivers/vfio/vfio_iommu_type1.c | 78 ++++++++++++++++++++++++++++++++++++++++-
>>>>> include/uapi/linux/vfio.h | 32 ++++++++++++++++-
>>>>> 2 files changed, 108 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
>>>>> index dc3ee5d..ce5e7eb 100644
>>>>> --- a/drivers/vfio/vfio_iommu_type1.c
>>>>> +++ b/drivers/vfio/vfio_iommu_type1.c
>>>>> @@ -38,6 +38,8 @@
>>>>> #include <linux/workqueue.h>
>>>>> #include <linux/dma-iommu.h>
>>>>> #include <linux/msi-doorbell.h>
>>>>> +#include <linux/irqdomain.h>
>>>>> +#include <linux/msi.h>
>>>>>
>>>>> #define DRIVER_VERSION "0.2"
>>>>> #define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>"
>>>>> @@ -1101,6 +1103,55 @@ static int vfio_domains_have_iommu_cache(struct vfio_iommu *iommu)
>>>>> return ret;
>>>>> }
>>>>>
>>>>> +static int compute_msi_geometry_caps(struct vfio_iommu *iommu,
>>>>> + struct vfio_info_cap *caps)
>>>>> +{
>>>>> + struct vfio_iommu_type1_info_cap_msi_geometry *vfio_msi_geometry;
>>>>> + unsigned long order = __ffs(vfio_pgsize_bitmap(iommu));
>>>>> + struct iommu_domain_msi_geometry msi_geometry;
>>>>> + struct vfio_info_cap_header *header;
>>>>> + struct vfio_domain *d;
>>>>> + bool reserved;
>>>>> + size_t size;
>>>>> +
>>>>> + mutex_lock(&iommu->lock);
>>>>> + /* All domains have same require_msi_map property, pick first */
>>>>> + d = list_first_entry(&iommu->domain_list, struct vfio_domain, next);
>>>>> + iommu_domain_get_attr(d->domain, DOMAIN_ATTR_MSI_GEOMETRY,
>>>>> + &msi_geometry);
>>>>> + reserved = !msi_geometry.iommu_msi_supported;
>>>>> +
>>>>> + mutex_unlock(&iommu->lock);
>>>>> +
>>>>> + size = sizeof(*vfio_msi_geometry);
>>>>> + header = vfio_info_cap_add(caps, size,
>>>>> + VFIO_IOMMU_TYPE1_INFO_CAP_MSI_GEOMETRY, 1);
>>>>> +
>>>>> + if (IS_ERR(header))
>>>>> + return PTR_ERR(header);
>>>>> +
>>>>> + vfio_msi_geometry = container_of(header,
>>>>> + struct vfio_iommu_type1_info_cap_msi_geometry,
>>>>> + header);
>>>>> +
>>>>> + vfio_msi_geometry->flags = reserved;
>>>>
>>>> Use the bit flag VFIO_IOMMU_MSI_GEOMETRY_RESERVED
>>>>
>>>>> + if (reserved) {
>>>>> + vfio_msi_geometry->aperture_start = msi_geometry.aperture_start;
>>>>> + vfio_msi_geometry->aperture_end = msi_geometry.aperture_end;
>>>>
>>>> But maybe nobody has set these, did you intend to use
>>>> iommu_domain_msi_aperture_valid(), which you defined early on but never
>>>> used?
>>>>
>>>>> + return 0;
>>>>> + }
>>>>> +
>>>>> + vfio_msi_geometry->order = order;
>>>>
>>>> I'm tempted to suggest that a user could do the same math on their own
>>>> since we provide the supported bitmap already... could it ever not be
>>>> the same?
>>>>
>>>>> + /*
>>>>> + * we compute a system-wide requirement based on all the registered
>>>>> + * doorbells
>>>>> + */
>>>>> + vfio_msi_geometry->size =
>>>>> + msi_doorbell_calc_pages(order) * ((uint64_t) 1 << order);
>>>>> +
>>>>> + return 0;
>>>>> +}
>>>>> +
>>>>> static long vfio_iommu_type1_ioctl(void *iommu_data,
>>>>> unsigned int cmd, unsigned long arg)
>>>>> {
>>>>> @@ -1122,8 +1173,10 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
>>>>> }
>>>>> } else if (cmd == VFIO_IOMMU_GET_INFO) {
>>>>> struct vfio_iommu_type1_info info;
>>>>> + struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
>>>>> + int ret;
>>>>>
>>>>> - minsz = offsetofend(struct vfio_iommu_type1_info, iova_pgsizes);
>>>>> + minsz = offsetofend(struct vfio_iommu_type1_info, cap_offset);
>>>>>
>>>>> if (copy_from_user(&info, (void __user *)arg, minsz))
>>>>> return -EFAULT;
>>>>> @@ -1135,6 +1188,29 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
>>>>>
>>>>> info.iova_pgsizes = vfio_pgsize_bitmap(iommu);
>>>>>
>>>>> + ret = compute_msi_geometry_caps(iommu, &caps);
>>>>> + if (ret)
>>>>> + return ret;
>>>>> +
>>>>> + if (caps.size) {
>>>>> + info.flags |= VFIO_IOMMU_INFO_CAPS;
>>>>> + if (info.argsz < sizeof(info) + caps.size) {
>>>>> + info.argsz = sizeof(info) + caps.size;
>>>>> + info.cap_offset = 0;
>>>>> + } else {
>>>>> + vfio_info_cap_shift(&caps, sizeof(info));
>>>>> + if (copy_to_user((void __user *)arg +
>>>>> + sizeof(info), caps.buf,
>>>>> + caps.size)) {
>>>>> + kfree(caps.buf);
>>>>> + return -EFAULT;
>>>>> + }
>>>>> + info.cap_offset = sizeof(info);
>>>>> + }
>>>>> +
>>>>> + kfree(caps.buf);
>>>>> + }
>>>>> +
>>>>> return copy_to_user((void __user *)arg, &info, minsz) ?
>>>>> -EFAULT : 0;
>>>>>
>>>>> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
>>>>> index 4a9dbc2..8dae013 100644
>>>>> --- a/include/uapi/linux/vfio.h
>>>>> +++ b/include/uapi/linux/vfio.h
>>>>> @@ -488,7 +488,35 @@ struct vfio_iommu_type1_info {
>>>>> __u32 argsz;
>>>>> __u32 flags;
>>>>> #define VFIO_IOMMU_INFO_PGSIZES (1 << 0) /* supported page sizes info */
>>>>> - __u64 iova_pgsizes; /* Bitmap of supported page sizes */
>>>>> +#define VFIO_IOMMU_INFO_CAPS (1 << 1) /* Info supports caps */
>>>>> + __u64 iova_pgsizes; /* Bitmap of supported page sizes */
>>>>> + __u32 __resv;
>>>>> + __u32 cap_offset; /* Offset within info struct of first cap */
>>>>> +};
>>>>
>>>> I understand the padding, but not the ordering. Why not end with
>>>> padding?
>>>>
>>>>> +
>>>>> +#define VFIO_IOMMU_TYPE1_INFO_CAP_MSI_GEOMETRY 1
>>>>> +
>>>>> +/*
>>>>> + * The MSI geometry capability allows to report the MSI IOVA geometry:
>>>>> + * - either the MSI IOVAs are constrained within a reserved IOVA aperture
>>>>> + * whose boundaries are given by [@aperture_start, @aperture_end].
>>>>> + * this is typically the case on x86 host. The userspace is not allowed
>>>>> + * to map userspace memory at IOVAs intersecting this range using
>>>>> + * VFIO_IOMMU_MAP_DMA.
>>>>> + * - or the MSI IOVAs are not requested to belong to any reserved range;
>>>>> + * in that case the userspace must provide an IOVA window characterized by
>>>>> + * @size and @alignment using VFIO_IOMMU_MAP_DMA with RESERVED_MSI_IOVA flag.
>>>>> + */
>>>>> +struct vfio_iommu_type1_info_cap_msi_geometry {
>>>>> + struct vfio_info_cap_header header;
>>>>> + __u32 flags;
>>>>> +#define VFIO_IOMMU_MSI_GEOMETRY_RESERVED (1 << 0) /* reserved geometry */
>>>>> + /* not reserved */
>>>>> + __u32 order; /* iommu page order used for aperture alignment*/
>>>>> + __u64 size; /* IOVA aperture size (bytes) the userspace must provide */
>>>>> + /* reserved */
>>>>> + __u64 aperture_start;
>>>>> + __u64 aperture_end;
>>>>
>>>> Should these be a union? We never set them both. Should the !reserved
>>>> case have a flag as well, so the user can positively identify what's
>>>> being provided?
>>>
>>> Actually, is there really any need to fit both of these within the same
>>> structure? Part of the idea of the capability chains is we can create
>>> a capability for each new thing we want to describe. So, we could
>>> simply define a generic reserved IOVA range capability with a 'start'
>>> and 'end' and then another capability to define MSI mapping
>>> requirements. Thanks,
>> Yes your suggested approach makes sense to me.
>>
>> One reason why I proceeded that way is we are mixing things at iommu.h
>> level too. Personally I would have preferred to separate things:
>> 1) add a new IOMMU_CAP_TRANSLATE_MSI capability in iommu_cap
>> 2) rename iommu_msi_supported into "programmable" bool: reporting
>> whether the aperture is reserved or programmable.
>>
>> In the early releases I think it was as above but slightly we moved to a
>> mixed description.
>>
>> What do you think?
>
> The API certainly doesn't seem like it has a cohesive feel to me. It's
> not entirely clear to me how we know when we need to register a DMA MSI
> cookie, or how we know that the MSI doorbell API is actually
> initialized and in use by the MSI/IOMMU layer, or exactly what is the
> MSI geometry telling me. Perhaps this is why the code doesn't seem to
> have a good rejection mechanism for architectures that need it versus
> those that don't, it's too hard to tell.
>
> Maybe we can look at what we think the user API should be and work
> backwards. For x86 we simply have a reserved range of IOVA. I'm not
> entirely sure it adds to the user API to know that it's for MSI, it's
> just a range of IOVAs that we cannot allocate for regular DMA. In
> fact, we currently lack a mechanism for describing the IOVA space of
> the IOMMU at all, so rather than focusing on a mechanism to describe a
> hole in the IOVA space, we might simply want to focus on a mechanism to
> describe the available IOVA space. Everybody needs that, not just
> x86. That sort of sounds like a VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE
> that perhaps looks like:
>
> struct vfio_iommu_type1_info_cap_iova_range {
> struct vfio_info_cap_header header;
> u64 start;
> u64 end;
> };
>
> Clearly we need to allow multiple of these in the capability chain
> since the existing x86 MSI range bisects this address space.
>
> To support this, we basically need the same information from the IOMMU
> API. We already have DOMAIN_ATTR_GEOMETRY, which should give us the
> base IOVA range, but we don't have anything describing the gaps. We
> don't know how many sources of gaps we'll have in the future, but let's
> keep it simple and assume we can look for MSI gaps and add other
> possible sources of gaps in the future, it's an internal API after all.
> So we can use DOMAIN_ATTR_MSI_GEOMETRY to tell us about the (we assume
> one) MSI range of reserved IOVA within DOMAIN_ATTR_GEOMETRY. For x86
> this is fixed, for SMMU this is a zero range until someone programs it.
>
> Now, what does a user need to know to add a reserved MSI IOVA range?
> They need to know a) that it needs to be done, and b) how big to make
> it (and maybe alignment requirements). Really all we need to describe
> then is b) since b) implies a). So maybe that gives us another
> capability chain entry:
>
> struct vfio_iommu_type1_info_cap_msi_resv {
> struct vfio_info_cap_header header;
> u64 size;
> u64 alignment;
> };
I like the approach and I like the idea to separate the 2 issues in
separate structs, both at VFIO level and IOMMU level. It makes even more
sense now we have the other requirement to handle host PCIe host bridge
window.
>
> It doesn't seem like we need to waste a flag bit on
> vfio_iommu_type1_info.flags for this since the existence of this
> capability would imply that VFIO_IOMMU_MAP_DMA supports an MSI_RESV
> flag.
I agree.
>
> So what do we need from the kernel infrastructure to make that happen?
> Well, we need a) and b) above, and again b) can imply a), so if the
> IOMMU API provided a DOMAIN_ATTR_MSI_RESV, providing the same
> size/alignment, then we're nearly there.
Agreed
Then we just need a way to
> set that range, which I'd probably try to plumb through the IOMMU API
> rather than pulling in separate doorbell APIs and DMA cookie APIs. If
> it's going to pull together all those different things, let's at least
> only do that in one place so we can expose a consistent API through the
> IOMMU API. Obviously once a range is set, DOMAIN_ATTR_MSI_RESV should
> report that range, so if the user were to look at the type1 info
> capability chain again, the available IOVA ranges would reflect the now
> reserved range.
So my plan is to respin the passthrough series with
vfio_iommu_type1_info_cap_msi_resv and associated iommu struct.
I would prefer to send a separate series to report IOVA usable address
space.
Thanks
Eric
>
> Maybe that's more than you're asking for, but that's the approach I
> would take to solidify the API. Thanks,
>
> Alex
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply
* [PATCH 5/9] drm/sun4i: Add compatible strings for A31/A31s display pipelines
From: Rob Herring @ 2016-10-10 14:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161006160629.11198-6-wens@csie.org>
On Fri, Oct 07, 2016 at 12:06:25AM +0800, Chen-Yu Tsai wrote:
> The A31's display pipeline has 2 frontends, 2 backends, and 2 TCONs. It
> also has new display enhancement blocks, such as the DRC (Dynamic Range
> Controller), the DEU (Display Enhancement Unit), and the CMU (Color
> Management Unit). It supports HDMI, MIPI DSI, and 2 LCD/LVDS channels.
>
> The A31s display pipeline is almost the same, just without MIPI DSI.
> Only the TCON seems to be different, due to the missing mux for MIPI
> DSI.
>
> Add compatible strings for both of them.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 4 ++++
> drivers/gpu/drm/sun4i/sun4i_backend.c | 1 +
> drivers/gpu/drm/sun4i/sun4i_drv.c | 3 +++
> 3 files changed, 8 insertions(+)
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH v13 03/15] iommu/dma: Allow MSI-only cookies
From: Auger Eric @ 2016-10-10 14:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6b944a74-7429-caf2-507d-30d6ae336bec@arm.com>
Hi Robin,
On 10/10/2016 16:26, Robin Murphy wrote:
> Hi Alex, Eric,
>
> On 06/10/16 21:17, Alex Williamson wrote:
>> On Thu, 6 Oct 2016 08:45:19 +0000
>> Eric Auger <eric.auger@redhat.com> wrote:
>>
>>> From: Robin Murphy <robin.murphy@arm.com>
>>>
>>> IOMMU domain users such as VFIO face a similar problem to DMA API ops
>>> with regard to mapping MSI messages in systems where the MSI write is
>>> subject to IOMMU translation. With the relevant infrastructure now in
>>> place for managed DMA domains, it's actually really simple for other
>>> users to piggyback off that and reap the benefits without giving up
>>> their own IOVA management, and without having to reinvent their own
>>> wheel in the MSI layer.
>>>
>>> Allow such users to opt into automatic MSI remapping by dedicating a
>>> region of their IOVA space to a managed cookie.
>>>
>>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>
>>> ---
>>>
>>> v1 -> v2:
>>> - compared to Robin's version
>>> - add NULL last param to iommu_dma_init_domain
>>> - set the msi_geometry aperture
>>> - I removed
>>> if (base < U64_MAX - size)
>>> reserve_iova(iovad, iova_pfn(iovad, base + size), ULONG_MAX);
>>> don't get why we would reserve something out of the scope of the iova domain?
>>> what do I miss?
>>> ---
>>> drivers/iommu/dma-iommu.c | 40 ++++++++++++++++++++++++++++++++++++++++
>>> include/linux/dma-iommu.h | 9 +++++++++
>>> 2 files changed, 49 insertions(+)
>>>
>>> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
>>> index c5ab866..11da1a0 100644
>>> --- a/drivers/iommu/dma-iommu.c
>>> +++ b/drivers/iommu/dma-iommu.c
>>> @@ -716,3 +716,43 @@ void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg)
>>> msg->address_lo += lower_32_bits(msi_page->iova);
>>> }
>>> }
>>> +
>>> +/**
>>> + * iommu_get_dma_msi_region_cookie - Configure a domain for MSI remapping only
>>
>> Should this perhaps be iommu_setup_dma_msi_region_cookie, or something
>> along those lines. I'm not sure what we're get'ing. Thanks,
>
> What we're getting is private third-party resources for the iommu_domain
> given in the argument. It's a get/put rather than alloc/free model since
> we operate opaquely on the domain as a container, rather than on the
> actual resource in question (an IOVA allocator).
>
> Since this particular use case is slightly different from the normal
> flow and has special initialisation requirements, it seemed a lot
> cleaner to simply combine that initialisation operation with the
> prerequisite "get" into a single call. Especially as it helps emphasise
> that this is not 'normal' DMA cookie usage.
I renamed iommu_get_dma_msi_region_cookie into
iommu_setup_dma_msi_region. Is it a problem for you?
>
>>
>> Alex
>>
>>> + * @domain: IOMMU domain to prepare
>>> + * @base: Base address of IOVA region to use as the MSI remapping aperture
>>> + * @size: Size of the desired MSI aperture
>>> + *
>>> + * Users who manage their own IOVA allocation and do not want DMA API support,
>>> + * but would still like to take advantage of automatic MSI remapping, can use
>>> + * this to initialise their own domain appropriately.
>>> + */
>>> +int iommu_get_dma_msi_region_cookie(struct iommu_domain *domain,
>>> + dma_addr_t base, u64 size)
>>> +{
>>> + struct iommu_dma_cookie *cookie;
>>> + struct iova_domain *iovad;
>>> + int ret;
>>> +
>>> + if (domain->type == IOMMU_DOMAIN_DMA)
>>> + return -EINVAL;
>>> +
>>> + ret = iommu_get_dma_cookie(domain);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + ret = iommu_dma_init_domain(domain, base, size, NULL);
>>> + if (ret) {
>>> + iommu_put_dma_cookie(domain);
>>> + return ret;
>>> + }
>
> It *is* necessary to explicitly reserve the upper part of the IOVA
> domain here - the aforementioned "special initialisation" - because
> dma_32bit_pfn is only an optimisation hint to prevent the allocator
> walking down from the very top of the the tree every time when devices
> with different DMA masks share a domain (I'm in two minds as to whether
> to tweak the way the iommu-dma code uses it in this respect, now that I
> fully understand things). The only actual upper limit to allocation is
> the DMA mask passed into each alloc_iova() call, so if we want to ensure
> IOVAs are really allocated within this specific region, we have to carve
> out everything above it.
thank you for the explanation. So I will restore the reserve then.
Thanks
Eric
>
> Robin.
>
>>> +
>>> + domain->msi_geometry.aperture_start = base;
>>> + domain->msi_geometry.aperture_end = base + size - 1;
>>> +
>>> + cookie = domain->iova_cookie;
>>> + iovad = &cookie->iovad;
>>> +
>>> + return 0;
>>> +}
>>> +EXPORT_SYMBOL(iommu_get_dma_msi_region_cookie);
>>> diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
>>> index 32c5890..1c55413 100644
>>> --- a/include/linux/dma-iommu.h
>>> +++ b/include/linux/dma-iommu.h
>>> @@ -67,6 +67,9 @@ int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
>>> /* The DMA API isn't _quite_ the whole story, though... */
>>> void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg);
>>>
>>> +int iommu_get_dma_msi_region_cookie(struct iommu_domain *domain,
>>> + dma_addr_t base, u64 size);
>>> +
>>> #else
>>>
>>> struct iommu_domain;
>>> @@ -90,6 +93,12 @@ static inline void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg)
>>> {
>>> }
>>>
>>> +static inline int iommu_get_dma_msi_region_cookie(struct iommu_domain *domain,
>>> + dma_addr_t base, u64 size)
>>> +{
>>> + return -ENODEV;
>>> +}
>>> +
>>> #endif /* CONFIG_IOMMU_DMA */
>>> #endif /* __KERNEL__ */
>>> #endif /* __DMA_IOMMU_H */
>>
>
^ permalink raw reply
* [PATCH 1/9] drm/sun4i: sun6i-drc: Support DRC on A31 and A31s
From: Rob Herring @ 2016-10-10 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161006160629.11198-2-wens@csie.org>
On Fri, Oct 07, 2016 at 12:06:21AM +0800, Chen-Yu Tsai wrote:
> The A31 and A31s also have the DRC as part of the display pipeline.
> As we know virtually nothing about them, just add compatible strings
> for both SoCs to the stub driver.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 2 ++
> drivers/gpu/drm/sun4i/sun6i_drc.c | 2 ++
> 2 files changed, 4 insertions(+)
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH] MAINTAINERS: Add ARM64-specific ACPI maintainers entry
From: Sudeep Holla @ 2016-10-10 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161005112540.22189-1-lorenzo.pieralisi@arm.com>
On 05/10/16 12:25, Lorenzo Pieralisi wrote:
> The ARM64 architecture defines ARM64 specific ACPI bindings to
> configure and set-up arch specific components. To simplify
> code reviews/updates and streamline the maintainership structure
> supporting the arch specific code, a new arm64 directory was created in
> /drivers/acpi, to contain ACPI code that is specific to ARM64
> architecture.
>
> Add the ARM64-specific ACPI maintainers entry in MAINTAINERS for
> the newly created subdirectory and respective code content.
>
> Lorenzo Pieralisi will be in charge of submitting and managing
> the pull requests on behalf of all maintainers listed.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Hanjun Guo <hanjun.guo@linaro.org>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
Acked-by: Sudeep Holla <sudeep.holla@arm.com>
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH] ARM: dts: imx6sx: Fix LCDIF interrupt type
From: Marek Vasut @ 2016-10-10 14:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476106556.2376.12.camel@pengutronix.de>
On 10/10/2016 03:35 PM, Lucas Stach wrote:
> Am Sonntag, den 02.10.2016, 18:44 +0200 schrieb Marek Vasut:
>> The LCDIF interrupt should be triggered by the rising edge of the
>> IRQ line because we only want the interrupt to trigger once per each
>> frame. It seems the LCDIF IRQ line cannot be explicitly de-asserted
>> by software, so the previous behavior before this patch, where the
>> interrupt was triggered by level-high status of the IRQ line, caused
>> the interrupt to fire again immediatelly after it was handled, which
>> caused the system to lock up due to the high rate of interrupts.
>>
> If there is no way to ack the IRQ how is the line going low again? Some
> hardware state machine?
My understanding is that it goes down at the end of VBLANK period.
>> Signed-off-by: Marek Vasut <marex@denx.de>
>> Cc: Lucas Stach <l.stach@pengutronix.de>
>> Cc: Fabio Estevam <fabio.estevam@nxp.com>
>> Cc: Shawn Guo <shawnguo@kernel.org>
>> ---
>> arch/arm/boot/dts/imx6sx.dtsi | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
>> index 1a473e8..9526c38 100644
>> --- a/arch/arm/boot/dts/imx6sx.dtsi
>> +++ b/arch/arm/boot/dts/imx6sx.dtsi
>> @@ -1143,7 +1143,7 @@
>> lcdif1: lcdif at 02220000 {
>> compatible = "fsl,imx6sx-lcdif", "fsl,imx28-lcdif";
>> reg = <0x02220000 0x4000>;
>> - interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
>> + interrupts = <GIC_SPI 5 IRQ_TYPE_EDGE_RISING>;
>> clocks = <&clks IMX6SX_CLK_LCDIF1_PIX>,
>> <&clks IMX6SX_CLK_LCDIF_APB>,
>> <&clks IMX6SX_CLK_DISPLAY_AXI>;
>> @@ -1154,7 +1154,7 @@
>> lcdif2: lcdif at 02224000 {
>> compatible = "fsl,imx6sx-lcdif", "fsl,imx28-lcdif";
>> reg = <0x02224000 0x4000>;
>> - interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
>> + interrupts = <GIC_SPI 6 IRQ_TYPE_EDGE_RISING>;
>> clocks = <&clks IMX6SX_CLK_LCDIF2_PIX>,
>> <&clks IMX6SX_CLK_LCDIF_APB>,
>> <&clks IMX6SX_CLK_DISPLAY_AXI>;
>
>
--
Best regards,
Marek Vasut
^ permalink raw reply
* [PATCH v4 2/8] scpi: Add alternative legacy structures, functions and macros
From: Sudeep Holla @ 2016-10-10 14:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475652814-30619-3-git-send-email-narmstrong@baylibre.com>
Hi Neil,
Sorry, I could not reply to your response on v3. Anyways I will review v4.
On 05/10/16 08:33, Neil Armstrong wrote:
> This patch adds support for the Legacy SCPI protocol in early JUNO versions and
> shipped Amlogic ARMv8 based SoCs. Some Rockchip SoC are also known to use this
> version of protocol with extended vendor commands
> .
> In order to support the legacy SCPI protocol variant, add back the structures
> and macros that varies against the final specification.
> Then add indirection table for legacy commands.
> Finally Add bitmap field for channel selection since the Legacy protocol mandates to
> send a selected subset of the commands on the high priority channel instead of the
> low priority channel.
>
> The message sending path differs from the final SCPI procotocol because the
> Amlogic SCP firmware always reply 1 instead of a special value containing the command
> byte and replied rx data length.
> For this reason commands queuing cannot be used and we assume the reply command is
> the head of the rx_pending list since we ensure sequential command sending with a
> separate dedicated mutex.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
> drivers/firmware/arm_scpi.c | 221 +++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 199 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
> index 498afa0..6244eb1 100644
> --- a/drivers/firmware/arm_scpi.c
> +++ b/drivers/firmware/arm_scpi.c
[...]
> @@ -307,21 +398,46 @@ static void scpi_process_cmd(struct scpi_chan *ch, u32 cmd)
> return;
> }
>
> - list_for_each_entry(t, &ch->rx_pending, node)
> - if (CMD_XTRACT_UNIQ(t->cmd) == CMD_XTRACT_UNIQ(cmd)) {
> - list_del(&t->node);
> - match = t;
> - break;
> - }
> + /* Command type is not replied by the SCP Firmware in legacy Mode
> + * We should consider that command is the head of pending RX commands
> + * if the list is not empty. In TX only mode, the list would be empty.
> + */
> + if (scpi_info->is_legacy) {
> + match = list_first_entry(&ch->rx_pending, struct scpi_xfer,
> + node);
> + list_del(&match->node);
> + } else {
> + list_for_each_entry(t, &ch->rx_pending, node)
> + if (CMD_XTRACT_UNIQ(t->cmd) == CMD_XTRACT_UNIQ(cmd)) {
> + list_del(&t->node);
> + match = t;
> + break;
> + }
> + }
> /* check if wait_for_completion is in progress or timed-out */
> if (match && !completion_done(&match->done)) {
> - struct scpi_shared_mem *mem = ch->rx_payload;
> - unsigned int len = min(match->rx_len, CMD_SIZE(cmd));
> + unsigned int len;
> +
> + if (scpi_info->is_legacy) {
> + struct legacy_scpi_shared_mem *mem = ch->rx_payload;
> +
> + /* RX Length is not replied by the lagcy Firmware */
> + len = match->rx_len;
> +
> + match->status = le32_to_cpu(mem->status);
> + memcpy_fromio(match->rx_buf, mem->payload, len);
The above 2 seems common to both, no ?
> + } else {
> + struct scpi_shared_mem *mem = ch->rx_payload;
> +
> + len = min(match->rx_len, CMD_SIZE(cmd));
> +
> + match->status = le32_to_cpu(mem->status);
> + memcpy_fromio(match->rx_buf, mem->payload, len);
> + }
>
> - match->status = le32_to_cpu(mem->status);
> - memcpy_fromio(match->rx_buf, mem->payload, len);
> if (match->rx_len > len)
> memset(match->rx_buf + len, 0, match->rx_len - len);
> +
Spurious ?
> complete(&match->done);
> }
> spin_unlock_irqrestore(&ch->rx_lock, flags);
> @@ -331,7 +447,12 @@ static void scpi_handle_remote_msg(struct mbox_client *c, void *msg)
> {
> struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
> struct scpi_shared_mem *mem = ch->rx_payload;
> - u32 cmd = le32_to_cpu(mem->command);
> + u32 cmd;
> +
> + if (scpi_info->is_legacy)
> + cmd = *(u32 *)msg;
Do we need do this if it doesn't contain command ?
> + else
> + cmd = le32_to_cpu(mem->command);
>
> scpi_process_cmd(ch, cmd);
> }
> @@ -343,17 +464,26 @@ static void scpi_tx_prepare(struct mbox_client *c, void *msg)
> struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
> struct scpi_shared_mem *mem = (struct scpi_shared_mem *)ch->tx_payload;
>
> - if (t->tx_buf)
> - memcpy_toio(mem->payload, t->tx_buf, t->tx_len);
> + if (t->tx_buf) {
> + if (scpi_info->is_legacy)
> + memcpy_toio(ch->tx_payload, t->tx_buf, t->tx_len);
> + else
> + memcpy_toio(mem->payload, t->tx_buf, t->tx_len);
> + }
> +
> if (t->rx_buf) {
> if (!(++ch->token))
> ++ch->token;
> ADD_SCPI_TOKEN(t->cmd, ch->token);
> + if (scpi_info->is_legacy)
> + t->slot = t->cmd;
I thought passing token was not an issue from your previous response,
but you are overriding it here, why ?
> spin_lock_irqsave(&ch->rx_lock, flags);
> list_add_tail(&t->node, &ch->rx_pending);
> spin_unlock_irqrestore(&ch->rx_lock, flags);
> }
> - mem->command = cpu_to_le32(t->cmd);
> +
> + if (!scpi_info->is_legacy)
> + mem->command = cpu_to_le32(t->cmd);
> }
>
> static struct scpi_xfer *get_scpi_xfer(struct scpi_chan *ch)
> @@ -396,21 +526,37 @@ static int scpi_send_message(unsigned int offset, void *tx_buf,
>
> cmd = scpi_info->scpi_cmds[offset];
>
> - chan = atomic_inc_return(&scpi_info->next_chan) % scpi_info->num_chans;
> + if (scpi_info->is_legacy)
> + chan = test_bit(cmd, scpi_info->cmd_priority) ? 1 : 0;
> + else
> + chan = atomic_inc_return(&scpi_info->next_chan) %
> + scpi_info->num_chans;
> scpi_chan = scpi_info->channels + chan;
>
> msg = get_scpi_xfer(scpi_chan);
> if (!msg)
> return -ENOMEM;
>
> - msg->slot = BIT(SCPI_SLOT);
> - msg->cmd = PACK_SCPI_CMD(cmd, tx_len);
> + if (scpi_info->is_legacy) {
> + msg->cmd = PACK_LEGACY_SCPI_CMD(cmd, tx_len);
> + msg->slot = msg->cmd;
> + } else {
> + msg->slot = BIT(SCPI_SLOT);
> + msg->cmd = PACK_SCPI_CMD(cmd, tx_len);
> + }
> msg->tx_buf = tx_buf;
> msg->tx_len = tx_len;
> msg->rx_buf = rx_buf;
> msg->rx_len = rx_len;
> init_completion(&msg->done);
>
> + /* Since we cannot distinguish the original command in the
> + * MHU reply stat value from a Legacy SCP firmware, ensure
> + * sequential command sending to the firmware.
> + */
OK this comment now questions the existence of this extra lock.
The mailbox will always send the commands in the sequential order.
It's only firmware that can re-order the response. Since that can't
happen in you case, I really don't see the need for this.
Please explain the race you would see without this locking. Yes I
understand that only one command is supposed to be sent to firmware at a
time. Suppose you allow more callers here, all will wait on the
completion flags and the first in the list gets unblocked right ?
I am just trying to understand if there's real need for this extra
lock when we already have that from the list.
> + if (scpi_info->is_legacy)
> + mutex_lock(&scpi_chan->legacy_lock);
> +
> ret = mbox_send_message(scpi_chan->chan, msg);
> if (ret < 0 || !rx_buf)
> goto out;
> @@ -421,9 +567,13 @@ static int scpi_send_message(unsigned int offset, void *tx_buf,
> /* first status word */
> ret = msg->status;
> out:
> - if (ret < 0 && rx_buf) /* remove entry from the list if timed-out */
> + if (ret < 0 && rx_buf)
> + /* remove entry from the list if timed-out */
> scpi_process_cmd(scpi_chan, msg->cmd);
>
> + if (scpi_info->is_legacy)
> + mutex_unlock(&scpi_chan->legacy_lock);
> +
> put_scpi_xfer(msg, scpi_chan);
> /* SCPI error codes > 0, translate them to Linux scale*/
> return ret > 0 ? scpi_to_linux_errno(ret) : ret;
[...]
> @@ -525,7 +687,6 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
>
> info->count = DVFS_OPP_COUNT(buf.header);
> info->latency = DVFS_LATENCY(buf.header) * 1000; /* uS to nS */
> -
Spurious ?
> info->opps = kcalloc(info->count, sizeof(*opp), GFP_KERNEL);
> if (!info->opps) {
> kfree(info);
> @@ -580,9 +741,13 @@ static int scpi_sensor_get_value(u16 sensor, u64 *val)
>
> ret = scpi_send_message(CMD_SENSOR_VALUE, &id, sizeof(id),
> &buf, sizeof(buf));
> - if (!ret)
> - *val = (u64)le32_to_cpu(buf.hi_val) << 32 |
> - le32_to_cpu(buf.lo_val);
> + if (!ret) {
> + if (scpi_info->is_legacy)
> + *val = (u64)le32_to_cpu(buf.lo_val);
> + else
> + *val = (u64)le32_to_cpu(buf.hi_val) << 32 |
> + le32_to_cpu(buf.lo_val);
> + }
Not required as I have mentioned couple of times in previous versions,
it's zero filled by the driver.
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH RESEND] ARM: dts: keystone-k2*: Increase SPI Flash partition size for U-Boot
From: Russell King - ARM Linux @ 2016-10-10 14:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161010141141.21333-1-vigneshr@ti.com>
On Mon, Oct 10, 2016 at 07:41:41PM +0530, Vignesh R wrote:
> U-Boot SPI Boot image is now more than 512KB for Keystone2 devices and
> cannot fit into existing partition. So, increase the SPI Flash partition
> for U-Boot to 1MB for all Keystone2 devices.
>
> Signed-off-by: Vignesh R <vigneshr@ti.com>
> ---
>
> This was submitted to v4.9 merge window but was never picked up:
> https://patchwork.kernel.org/patch/9135023/
I think you need to explain why it's safe to change the layout of the
flash partitions like this.
- What is this "misc" partition?
- Why is it safe to move the "misc" partition in this way?
- Do users need to do anything with data stored in the "misc" partition
when changing kernels?
If the "misc" partition is simply unused space on the flash device, why
list it in DT?
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH 0/4] soc: renesas: Identify SoC and register with the SoC bus
From: Arnd Bergmann @ 2016-10-10 14:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475572167-29581-1-git-send-email-geert+renesas@glider.be>
On Tuesday, October 4, 2016 11:09:23 AM CEST Geert Uytterhoeven wrote:
> Hi all,
>
> Some Renesas SoCs may exist in different revisions, providing slightly
> different functionalities (e.g. R-Car H3 ES1.x and ES2.0). This needs to
> be catered for by drivers and/or platform code. The recently proposed
> soc_device_match() API seems like a good fit to handle this.
>
> This patch series implements the core infrastructure to provide SoC and
> revision information through the SoC bus for Renesas ARM SoCs. It
> consists of 4 patches:
> - Patch 1 avoids a crash when SoC revision information is needed and
> provided early,
> - Patch 2 (from Arnd) introduces the soc_device_match() API.
> I don't know if, when, and through which channel this patch is
> planned to go upstream,
> - Patch 3 fixes a bug in soc_device_match(), causing a crash when
> trying to match on an SoC attribute that is not provided (seen on
> EMEV2, RZ/A, and R-Car M1A, which lack revision information),
> - Patch 4 identifies Renesas SoCs and registers them with the SoC bus.
>
> Tested on (family, machine, soc_id, optional revision):
>
> Emma Mobile EV2, EMEV2 KZM9D Board, emev2
> RZ/A, Genmai, r7s72100
> R-Mobile, APE6EVM, r8a73a4, ES1.0
> R-Mobile, armadillo 800 eva, r8a7740, ES2.0
> R-Car Gen1, bockw, r8a7778
> R-Car Gen1, marzen, r8a7779, ES1.0
> R-Car Gen2, Lager, r8a7790, ES1.0
> R-Car Gen2, Koelsch, r8a7791, ES1.0
> R-Car Gen2, Gose, r8a7793, ES1.0
> R-Car Gen2, Alt, r8a7794, ES1.0
> R-Car Gen3, Renesas Salvator-X board based on r8a7795, r8a7795, ES1.0
> R-Car Gen3, Renesas Salvator-X board based on r8a7796, r8a7796, ES1.0
> SH-Mobile, KZM-A9-GT, sh73a0, ES2.0
As mentioned in the comment for the driver patch, I think this makes
a lot of sense for the machines that have a revision register, in
particular when the interpretation of that register is always done
the same way, but I'm a bit skeptical about doing it in the same driver
for machines that don't have the register.
Matching by a device rather than the SoC platform also has the advantage
that there is no need to maintain a list of compatible numbers in the
driver.
Arnd
^ permalink raw reply
* [PATCH v13 03/15] iommu/dma: Allow MSI-only cookies
From: Robin Murphy @ 2016-10-10 14:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161006141717.13c9c111@t450s.home>
Hi Alex, Eric,
On 06/10/16 21:17, Alex Williamson wrote:
> On Thu, 6 Oct 2016 08:45:19 +0000
> Eric Auger <eric.auger@redhat.com> wrote:
>
>> From: Robin Murphy <robin.murphy@arm.com>
>>
>> IOMMU domain users such as VFIO face a similar problem to DMA API ops
>> with regard to mapping MSI messages in systems where the MSI write is
>> subject to IOMMU translation. With the relevant infrastructure now in
>> place for managed DMA domains, it's actually really simple for other
>> users to piggyback off that and reap the benefits without giving up
>> their own IOVA management, and without having to reinvent their own
>> wheel in the MSI layer.
>>
>> Allow such users to opt into automatic MSI remapping by dedicating a
>> region of their IOVA space to a managed cookie.
>>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>
>> ---
>>
>> v1 -> v2:
>> - compared to Robin's version
>> - add NULL last param to iommu_dma_init_domain
>> - set the msi_geometry aperture
>> - I removed
>> if (base < U64_MAX - size)
>> reserve_iova(iovad, iova_pfn(iovad, base + size), ULONG_MAX);
>> don't get why we would reserve something out of the scope of the iova domain?
>> what do I miss?
>> ---
>> drivers/iommu/dma-iommu.c | 40 ++++++++++++++++++++++++++++++++++++++++
>> include/linux/dma-iommu.h | 9 +++++++++
>> 2 files changed, 49 insertions(+)
>>
>> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
>> index c5ab866..11da1a0 100644
>> --- a/drivers/iommu/dma-iommu.c
>> +++ b/drivers/iommu/dma-iommu.c
>> @@ -716,3 +716,43 @@ void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg)
>> msg->address_lo += lower_32_bits(msi_page->iova);
>> }
>> }
>> +
>> +/**
>> + * iommu_get_dma_msi_region_cookie - Configure a domain for MSI remapping only
>
> Should this perhaps be iommu_setup_dma_msi_region_cookie, or something
> along those lines. I'm not sure what we're get'ing. Thanks,
What we're getting is private third-party resources for the iommu_domain
given in the argument. It's a get/put rather than alloc/free model since
we operate opaquely on the domain as a container, rather than on the
actual resource in question (an IOVA allocator).
Since this particular use case is slightly different from the normal
flow and has special initialisation requirements, it seemed a lot
cleaner to simply combine that initialisation operation with the
prerequisite "get" into a single call. Especially as it helps emphasise
that this is not 'normal' DMA cookie usage.
>
> Alex
>
>> + * @domain: IOMMU domain to prepare
>> + * @base: Base address of IOVA region to use as the MSI remapping aperture
>> + * @size: Size of the desired MSI aperture
>> + *
>> + * Users who manage their own IOVA allocation and do not want DMA API support,
>> + * but would still like to take advantage of automatic MSI remapping, can use
>> + * this to initialise their own domain appropriately.
>> + */
>> +int iommu_get_dma_msi_region_cookie(struct iommu_domain *domain,
>> + dma_addr_t base, u64 size)
>> +{
>> + struct iommu_dma_cookie *cookie;
>> + struct iova_domain *iovad;
>> + int ret;
>> +
>> + if (domain->type == IOMMU_DOMAIN_DMA)
>> + return -EINVAL;
>> +
>> + ret = iommu_get_dma_cookie(domain);
>> + if (ret)
>> + return ret;
>> +
>> + ret = iommu_dma_init_domain(domain, base, size, NULL);
>> + if (ret) {
>> + iommu_put_dma_cookie(domain);
>> + return ret;
>> + }
It *is* necessary to explicitly reserve the upper part of the IOVA
domain here - the aforementioned "special initialisation" - because
dma_32bit_pfn is only an optimisation hint to prevent the allocator
walking down from the very top of the the tree every time when devices
with different DMA masks share a domain (I'm in two minds as to whether
to tweak the way the iommu-dma code uses it in this respect, now that I
fully understand things). The only actual upper limit to allocation is
the DMA mask passed into each alloc_iova() call, so if we want to ensure
IOVAs are really allocated within this specific region, we have to carve
out everything above it.
Robin.
>> +
>> + domain->msi_geometry.aperture_start = base;
>> + domain->msi_geometry.aperture_end = base + size - 1;
>> +
>> + cookie = domain->iova_cookie;
>> + iovad = &cookie->iovad;
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL(iommu_get_dma_msi_region_cookie);
>> diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
>> index 32c5890..1c55413 100644
>> --- a/include/linux/dma-iommu.h
>> +++ b/include/linux/dma-iommu.h
>> @@ -67,6 +67,9 @@ int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
>> /* The DMA API isn't _quite_ the whole story, though... */
>> void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg);
>>
>> +int iommu_get_dma_msi_region_cookie(struct iommu_domain *domain,
>> + dma_addr_t base, u64 size);
>> +
>> #else
>>
>> struct iommu_domain;
>> @@ -90,6 +93,12 @@ static inline void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg)
>> {
>> }
>>
>> +static inline int iommu_get_dma_msi_region_cookie(struct iommu_domain *domain,
>> + dma_addr_t base, u64 size)
>> +{
>> + return -ENODEV;
>> +}
>> +
>> #endif /* CONFIG_IOMMU_DMA */
>> #endif /* __KERNEL__ */
>> #endif /* __DMA_IOMMU_H */
>
^ permalink raw reply
* [PATCH/RFC 4/4] soc: renesas: Identify SoC and register with the SoC bus
From: Arnd Bergmann @ 2016-10-10 14:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475572167-29581-5-git-send-email-geert+renesas@glider.be>
On Tuesday, October 4, 2016 11:09:27 AM CEST Geert Uytterhoeven wrote:
> Identify the SoC type and revision, and register this information with
> the SoC bus, so it is available under /sys/devices/soc0/, and can be
> checked where needed using soc_device_match().
>
> In addition, on SoCs that support it, the product ID is read from a
> hardware register and validated, to catch accidental use of a DTB for a
> different SoC.
>
> Example:
>
> Detected Renesas r8a7791 ES1.0
> ...
> # cat /sys/devices/soc0/{family,machine,soc_id,revision}
> R-Car Gen2
> Koelsch
> r8a7791
> ES1.0
>
Seems all reasonable.
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> This patch does NOT add a call to
>
> of_platform_default_populate(NULL, NULL,
> soc_device_to_device(soc_dev));
>
> Contrary to suggested by commit 74d1d82cdaaec727 ("drivers/base: add bus
> for System-on-Chip devices), doing so would not only move on-SoC devices
> from /sys/devices/platform/ to /sys/devices/soc0/, but also all other
> board (off-SoC) devices specified in the DTB.
Right, we have moved away from that a while ago, and now just
use the device for identification, not to model the device
hierarchy.
> diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
> new file mode 100644
> index 0000000000000000..74b72e4112b8889e
> --- /dev/null
> +++ b/drivers/soc/renesas/renesas-soc.c
> @@ -0,0 +1,266 @@
> +/*
> + * Renesas SoC Identification
> + *
> + * Copyright (C) 2014-2016 Glider bvba
> + *
> + * 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; version 2 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/sys_soc.h>
> +
> +
> +struct renesas_family {
> + const char name[16];
> + u32 reg; /* CCCR, PVR, or PRR */
> +};
> +
> +static const struct renesas_family fam_emev2 __initconst = {
> + .name = "Emma Mobile EV2",
> +};
As this is not related to the others and doesn't have the respective
register, I'd leave the platform out of this, and possibly have
a separate driver for it.
> +static const struct renesas_family fam_rza __initconst = {
> + .name = "RZ/A",
> +};
I'm not sure about the relationship between this one and the others,
maybe it should be treated in the same way as emev2 and left out from
this driver?
> +static const struct renesas_family fam_rmobile __initconst = {
> + .name = "R-Mobile",
> + .reg = 0xe600101c, /* CCCR (Common Chip Code Register) */
> +};
> +
> +static const struct renesas_family fam_rcar_gen1 __initconst = {
> + .name = "R-Car Gen1",
> + .reg = 0xff000044, /* PRR (Product Register) */
> +};
> +
> +static const struct renesas_family fam_rcar_gen2 __initconst = {
> + .name = "R-Car Gen2",
> + .reg = 0xff000044, /* PRR (Product Register) */
> +};
> +
> +static const struct renesas_family fam_rcar_gen3 __initconst = {
> + .name = "R-Car Gen3",
> + .reg = 0xfff00044, /* PRR (Product Register) */
> +};
> +
> +static const struct renesas_family fam_rzg __initconst = {
> + .name = "RZ/G",
> + .reg = 0xff000044, /* PRR (Product Register) */
> +};
> +
> +static const struct renesas_family fam_shmobile __initconst = {
> + .name = "SH-Mobile",
> + .reg = 0xe600101c, /* CCCR (Common Chip Code Register) */
> +};
These seem to fall into two distinct categories, maybe there is a
better way to group them. What device contain the two kinds of
registers (PRR, CCCR)?
Hardcoding the register address seems rather ugly here, so maybe
there is a way to have two separate probe methods based on the
surrounding register range, and then bind to that?
> +static const struct of_device_id renesas_socs[] __initconst = {
> +#ifdef CONFIG_ARCH_EMEV2
> + { .compatible = "renesas,emev2", .data = &soc_emev2 },
> +#endif
> +#ifdef CONFIG_ARCH_R7S72100
> + { .compatible = "renesas,r7s72100", .data = &soc_rz_a1h },
> +#endif
> +#ifdef CONFIG_ARCH_R8A73A4
I think the #ifdefs here will result in warnings for unused symbols
when the Kconfig symbols are disabled.
Arnd
^ permalink raw reply
* MAINTAINERS entry for ARM/CLKDEV SUPPORT
From: Russell King - ARM Linux @ 2016-10-10 14:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161010140810.GA30609@mwanda>
On Mon, Oct 10, 2016 at 05:08:10PM +0300, Dan Carpenter wrote:
> Hello Stephen Boyd,
Okay, that's really not nice.
This is _not_ a question for Stephen. Stephen does _not_ co-maintain
clkdev or the clk API, but co-maintains CCF. I've no idea why you are
addressing this to Stephen when this is clearly a question for me to
answer.
> The MAINTAINERS entry looks like this:
>
> ARM/CLKDEV SUPPORT
> M: Russell King <linux@armlinux.org.uk>
> L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> S: Maintained
> F: arch/arm/include/asm/clkdev.h
> F: drivers/clk/clkdev.c
>
>
> We removed arch/arm/include/asm/clkdev.h in 34d2f4d3a4d6a6b ('ARM: Use
> generic clkdev.h header'). Do you still need to be CC'd on the clkdev.c
> changes?
Technically, it is redundant anyway, as I'm listed for all arch/arm
changes. However, the maintainership of arch/arm and the maintainership
of clkdev are separate, the explicit entry is quite right.
It's also right that it's retained, because if we stop using the generic
clkdev.h header, I want to be copied on such a change, and this entry
will allow checkpatch to list me as clkdev maintainer.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH 1/2] host: ehci-exynos: Convert to use the SET_SYSTEM_SLEEP_PM_OPS
From: Anand Moon @ 2016-10-10 14:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.44L0.1610091713490.1734-100000@netrider.rowland.org>
hi Alan/Krzysztof,
On 10 October 2016 at 02:47, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Sun, 9 Oct 2016, Krzysztof Kozlowski wrote:
>
>> On Sun, Oct 09, 2016 at 02:34:14PM +0000, Anand Moon wrote:
>> > Move the ehci-exynos system PM callbacks within #ifdef CONFIG_PM_SLEEP
>> > as to avoid them being build when not used. This also allows us to use the
>> > SET_SYSTEM_SLEEP_PM_OPS macro which simplifies the code.
>> >
>> > Signed-off-by: Anand Moon <linux.amoon@gmail.com>
>> > ---
>> > drivers/usb/host/ehci-exynos.c | 14 ++++++--------
>> > 1 file changed, 6 insertions(+), 8 deletions(-)
>> >
>> > diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
>> > index 42e5b66..1899900 100644
>> > --- a/drivers/usb/host/ehci-exynos.c
>> > +++ b/drivers/usb/host/ehci-exynos.c
>> > @@ -251,7 +251,7 @@ static int exynos_ehci_remove(struct platform_device *pdev)
>> > return 0;
>> > }
>> >
>> > -#ifdef CONFIG_PM
>> > +#ifdef CONFIG_PM_SLEEP
>>
>> Does not look like an equivalent change. How will it behave in a config
>> with !SUSPEND && !HIBERNATE && PM?
>
> It's hard to say what Anand originally had in mind. To me, it looks
> like it will behave exactly the same as before, the only difference
> being that the object image will not contain unused exynos_ehci_suspend
> and exynos_ehci_resume routines. And the compiler won't issue a
> warning at build time that the routines are unused.
>
> Alan Stern
>
Thanks for looking into this closely.
I will just send one line changes to use SET_SYSTEM_SLEEP_PM_OPS
with better commit logs, if you people agree with this.
Best Regards
-Anand Moon
^ permalink raw reply
* [PATCH 1/4] base: soc: Early register bus when needed
From: Arnd Bergmann @ 2016-10-10 14:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475572167-29581-2-git-send-email-geert+renesas@glider.be>
On Tuesday, October 4, 2016 11:09:24 AM CEST Geert Uytterhoeven wrote:
> If soc_device_register() is called before soc_bus_register(), it crashes
> with a NULL pointer dereference.
>
> soc_bus_register() is already a core_initcall(), but drivers/base/ is
> entered later than e.g. drivers/pinctrl/ and drivers/soc/. Hence there
> are several subsystems that may need to know SoC revision information,
> while it's not so easy to initialize the SoC bus even earlier using an
> initcall.
>
> To fix this, let soc_device_register() register the bus early if that
> hasn't happened yet.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>
Not nice, but I can't think of a better alternative, so
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* [PATCH 3/4] base: soc: Check for NULL SoC device attributes
From: Arnd Bergmann @ 2016-10-10 14:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475572167-29581-4-git-send-email-geert+renesas@glider.be>
On Tuesday, October 4, 2016 11:09:26 AM CEST Geert Uytterhoeven wrote:
> If soc_device_match() is used to check the value of a specific
> attribute that is not present for the current SoC, the kernel crashes
> with a NULL pointer dereference.
>
> Fix this by explicitly checking for the absence of a needed property,
> and considering this a non-match.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* [PATCH RESEND] ARM: dts: keystone-k2*: Increase SPI Flash partition size for U-Boot
From: Vignesh R @ 2016-10-10 14:11 UTC (permalink / raw)
To: linux-arm-kernel
U-Boot SPI Boot image is now more than 512KB for Keystone2 devices and
cannot fit into existing partition. So, increase the SPI Flash partition
for U-Boot to 1MB for all Keystone2 devices.
Signed-off-by: Vignesh R <vigneshr@ti.com>
---
This was submitted to v4.9 merge window but was never picked up:
https://patchwork.kernel.org/patch/9135023/
arch/arm/boot/dts/keystone-k2e-evm.dts | 4 ++--
arch/arm/boot/dts/keystone-k2hk-evm.dts | 4 ++--
arch/arm/boot/dts/keystone-k2l-evm.dts | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/keystone-k2e-evm.dts b/arch/arm/boot/dts/keystone-k2e-evm.dts
index ae1ebe7ee021..08ca9dc6ef7c 100644
--- a/arch/arm/boot/dts/keystone-k2e-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2e-evm.dts
@@ -137,13 +137,13 @@
partition at 0 {
label = "u-boot-spl";
- reg = <0x0 0x80000>;
+ reg = <0x0 0x100000>;
read-only;
};
partition at 1 {
label = "misc";
- reg = <0x80000 0xf80000>;
+ reg = <0x100000 0xf00000>;
};
};
};
diff --git a/arch/arm/boot/dts/keystone-k2hk-evm.dts b/arch/arm/boot/dts/keystone-k2hk-evm.dts
index 2156ff92d08f..369e1245f1ba 100644
--- a/arch/arm/boot/dts/keystone-k2hk-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2hk-evm.dts
@@ -161,13 +161,13 @@
partition at 0 {
label = "u-boot-spl";
- reg = <0x0 0x80000>;
+ reg = <0x0 0x100000>;
read-only;
};
partition at 1 {
label = "misc";
- reg = <0x80000 0xf80000>;
+ reg = <0x100000 0xf00000>;
};
};
};
diff --git a/arch/arm/boot/dts/keystone-k2l-evm.dts b/arch/arm/boot/dts/keystone-k2l-evm.dts
index 056b42f99d7a..63ae65987ca5 100644
--- a/arch/arm/boot/dts/keystone-k2l-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2l-evm.dts
@@ -110,13 +110,13 @@
partition at 0 {
label = "u-boot-spl";
- reg = <0x0 0x80000>;
+ reg = <0x0 0x100000>;
read-only;
};
partition at 1 {
label = "misc";
- reg = <0x80000 0xf80000>;
+ reg = <0x100000 0xf00000>;
};
};
};
--
2.10.1
^ permalink raw reply related
* [PATCH v2 1/2] clk: imx: fix integer overflow in AV PLL round rate
From: Fabio Estevam @ 2016-10-10 14:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4e8696869cc82443825a590966bbd3a265befdfa.1476092427.git.emil@limesaudio.com>
On Mon, Oct 10, 2016 at 7:03 AM, Emil Lundmark <emil@limesaudio.com> wrote:
> Since 'parent_rate * mfn' may overflow 32 bits, the result should be
> stored using 64 bits.
It would be nice to add the text you put in the cover letter where you
explain the PLL4 clock discrepancy here in the commit log.
>
> Fixes: ba7f4f557eb6 ("clk: imx: correct AV PLL rate formula")
Would be nice to Cc the author of this commit (Anson Huang). Added on Cc.
Another hint: ./scripts/get_maintainer.pl drivers/clk/imx/clk-pllv3.c
gives you some suggestions on people and lists to add to Cc.
^ permalink raw reply
* MAINTAINERS entry for ARM/CLKDEV SUPPORT
From: Dan Carpenter @ 2016-10-10 14:08 UTC (permalink / raw)
To: linux-arm-kernel
Hello Stephen Boyd,
The MAINTAINERS entry looks like this:
ARM/CLKDEV SUPPORT
M: Russell King <linux@armlinux.org.uk>
L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/include/asm/clkdev.h
F: drivers/clk/clkdev.c
We removed arch/arm/include/asm/clkdev.h in 34d2f4d3a4d6a6b ('ARM: Use
generic clkdev.h header'). Do you still need to be CC'd on the clkdev.c
changes?
regards,
dan carpenter
^ permalink raw reply
* [PATCH v2 1/2] clk: imx: fix integer overflow in AV PLL round rate
From: Uwe Kleine-König @ 2016-10-10 13:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4e8696869cc82443825a590966bbd3a265befdfa.1476092427.git.emil@limesaudio.com>
On Mon, Oct 10, 2016 at 12:03:05PM +0200, Emil Lundmark wrote:
> Since 'parent_rate * mfn' may overflow 32 bits, the result should be
> stored using 64 bits.
>
> Fixes: ba7f4f557eb6 ("clk: imx: correct AV PLL rate formula")
> Signed-off-by: Emil Lundmark <emil@limesaudio.com>
> ---
> drivers/clk/imx/clk-pllv3.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
> index 19f9b622981a..bc7f163ea13c 100644
> --- a/drivers/clk/imx/clk-pllv3.c
> +++ b/drivers/clk/imx/clk-pllv3.c
> @@ -247,7 +247,11 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
> do_div(temp64, parent_rate);
> mfn = temp64;
>
> - return parent_rate * div + parent_rate * mfn / mfd;
> + temp64 = (u64)parent_rate;
> + temp64 *= mfn;
> + do_div(temp64, mfd);
If you change parent_rate from unsigned long to u64 this simplifies to
temp64 = parent_rate * mfn
do_div(temp64, mfd);
> +
> + return parent_rate * div + (u32)temp64;
When thinking about overflow problems: Should this fail somehow if
temp64 != (u32)temp64?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH v2 1/5] clk: add support for runtime pm
From: Ulf Hansson @ 2016-10-10 13:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <86cd1c31-6265-7493-fe6d-9a64fc34cd65@samsung.com>
[...]
>>> @@ -157,11 +181,17 @@ static bool clk_core_is_prepared(struct clk_core
>>> *core)
>>> if (!core->ops->is_prepared)
>>> return core->prepare_count;
>>>
>>> - return core->ops->is_prepared(core->hw);
>>> + clk_pm_runtime_get(core);
>>
>> I guess you should assign status to the return code, and check it.
>
>
> Okay. I assume that in case of any failure from runtime pm, the function
> should return false?
I think so, yes.
>
>
[...]
>>> static void clk_disable_unused_subtree(struct clk_core *core)
>>> @@ -768,6 +834,9 @@ static void clk_disable_unused_subtree(struct
>>> clk_core *core)
>>> if (core->flags & CLK_OPS_PARENT_ENABLE)
>>> clk_core_prepare_enable(core->parent);
>>>
>>> + if (clk_pm_runtime_get(core) != 0)
>>
>> Is there any reason to why you haven't moved this further down in this
>> function, like just before calling clk_core_is_enabled()?
>
>
> Yes, clk_enable_lock() takes a spinlock, so I cannot call pm_runtime_get
> after it.
Of course, you are right!
>
>
>>
>> You may also simplify this:
>> if (clk_pm_runtime_get(core))
>>
>>> + return;
>>> +
>>
>> You need to restore the call made to clk_core_prepare_enable()
>> earlier, so please update the error handling to cope with this.
>>
[...]
>>> @@ -2546,6 +2631,8 @@ struct clk *clk_register(struct device *dev, struct
>>> clk_hw *hw)
>>> goto fail_name;
>>> }
>>> core->ops = hw->init->ops;
>>> + if (dev && (hw->init->flags & CLK_RUNTIME_PM))
>>> + core->dev = dev;
>>
>> I guess you need this to play safe, although I am really wondering if
>> we should try without.
>>
>> Not that many clocks are currently being registered with a valid
>> struct device pointer. For the other cases why not try to use runtime
>> PM as per default?
>
>
> I've that tried initially, but it causes failure for all the clock
> controllers, which don't enable runtime pm. One of such case is max77686
> PMIC, which provides 3 clocks. Maybe a negative flag (CLK_NO_RUNTIME_PM)
> will be a better solution, so by default the runtime pm calls will be
> enabled for every driver providing struct device?
I assume that's because the runtime PM errors in clk_pm_runtime_get()
and friends, are being propagated to the callers? Especially because
the runtime PM core returns error codes, in cases when runtime PM
hasn't been enabled for the device.
>
>> Moreover we anyway rely on the clock provider to enable runtime PM for
>> the clock device, and when that isn't the case the runtime PM
>> deployment in the core should still be safe, right!?
>
>
> I don't get the above comment. Do you want to check if runtime pm has
> been enabled during clock registration?
Yes, something like that. Apologize, I was clearly being too vague.
My point is, we don't need to invent a specific clock provider flag
for this. Instead the clock core could just at clock registration
check if runtime PM is enabled for the device (pm_runtime_enabled()),.
and from that assign an internal clock core flag to keep track of
whether runtime PM should be managed or not.
>
>>> if (dev && dev->driver)
>>> core->owner = dev->driver->owner;
>>> core->hw = hw;
>>> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
>>> index a39c0c530778..8a131eb71fdf 100644
>>> --- a/include/linux/clk-provider.h
>>> +++ b/include/linux/clk-provider.h
>>> @@ -35,6 +35,7 @@
>>> #define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */
>>> /* parents need enable during gate/ungate, set rate and re-parent */
>>> #define CLK_OPS_PARENT_ENABLE BIT(12)
>>> +#define CLK_RUNTIME_PM BIT(13)
>>>
>>> struct clk;
>>> struct clk_hw;
>>> --
>>> 1.9.1
>>>
>>
>
> Best regards
> --
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
>
Kind regards
Uffe
^ permalink raw reply
* [PATCH] ARM: dts: imx6sx: Fix LCDIF interrupt type
From: Lucas Stach @ 2016-10-10 13:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161002164435.5812-1-marex@denx.de>
Am Sonntag, den 02.10.2016, 18:44 +0200 schrieb Marek Vasut:
> The LCDIF interrupt should be triggered by the rising edge of the
> IRQ line because we only want the interrupt to trigger once per each
> frame. It seems the LCDIF IRQ line cannot be explicitly de-asserted
> by software, so the previous behavior before this patch, where the
> interrupt was triggered by level-high status of the IRQ line, caused
> the interrupt to fire again immediatelly after it was handled, which
> caused the system to lock up due to the high rate of interrupts.
>
If there is no way to ack the IRQ how is the line going low again? Some
hardware state machine?
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Shawn Guo <shawnguo@kernel.org>
> ---
> arch/arm/boot/dts/imx6sx.dtsi | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
> index 1a473e8..9526c38 100644
> --- a/arch/arm/boot/dts/imx6sx.dtsi
> +++ b/arch/arm/boot/dts/imx6sx.dtsi
> @@ -1143,7 +1143,7 @@
> lcdif1: lcdif at 02220000 {
> compatible = "fsl,imx6sx-lcdif", "fsl,imx28-lcdif";
> reg = <0x02220000 0x4000>;
> - interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
> + interrupts = <GIC_SPI 5 IRQ_TYPE_EDGE_RISING>;
> clocks = <&clks IMX6SX_CLK_LCDIF1_PIX>,
> <&clks IMX6SX_CLK_LCDIF_APB>,
> <&clks IMX6SX_CLK_DISPLAY_AXI>;
> @@ -1154,7 +1154,7 @@
> lcdif2: lcdif at 02224000 {
> compatible = "fsl,imx6sx-lcdif", "fsl,imx28-lcdif";
> reg = <0x02224000 0x4000>;
> - interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
> + interrupts = <GIC_SPI 6 IRQ_TYPE_EDGE_RISING>;
> clocks = <&clks IMX6SX_CLK_LCDIF2_PIX>,
> <&clks IMX6SX_CLK_LCDIF_APB>,
> <&clks IMX6SX_CLK_DISPLAY_AXI>;
^ permalink raw reply
* [PATCH v3 1/4] net: phy: dp83867: Add documentation for optional impedance control
From: Rob Herring @ 2016-10-10 13:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161006051355.15947-2-mugunthanvnm@ti.com>
On Thu, Oct 06, 2016 at 10:43:52AM +0530, Mugunthan V N wrote:
> Add documention of ti,impedance-control which can be used to
Needs updating.
> correct MAC impedance mismatch using phy extended registers.
>
> Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
> ---
> Documentation/devicetree/bindings/net/ti,dp83867.txt | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/net/ti,dp83867.txt b/Documentation/devicetree/bindings/net/ti,dp83867.txt
> index 5d21141..85bf945 100644
> --- a/Documentation/devicetree/bindings/net/ti,dp83867.txt
> +++ b/Documentation/devicetree/bindings/net/ti,dp83867.txt
> @@ -9,6 +9,18 @@ Required properties:
> - ti,fifo-depth - Transmitt FIFO depth- see dt-bindings/net/ti-dp83867.h
> for applicable values
>
> +Optional property:
> + - ti,min-output-impedance - MAC Interface Impedance control to set
> + the programmable output impedance to
> + minimum value (35 ohms).
> + - ti,max-output-impedance - MAC Interface Impedance control to set
> + the programmable output impedance to
> + maximum value (70 ohms).
Define what are valid range of values for these.
> +
> +Note: ti,min-output-impedance and ti,max-output-impedance are mutually
> + exclusive. When both properties are present ti,max-output-impedance
> + takes precedence.
> +
> Default child nodes are standard Ethernet PHY device
> nodes as described in Documentation/devicetree/bindings/net/phy.txt
>
> --
> 2.10.0.372.g6fe1b14
>
^ permalink raw reply
* [PATCH 2/3] dt-bindings: mtd: add DT binding for s3c2410 flash controller
From: Rob Herring @ 2016-10-10 13:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475711217-974-3-git-send-email-sergio.prado@e-labworks.com>
On Wed, Oct 05, 2016 at 08:46:56PM -0300, Sergio Prado wrote:
> Adds the device tree bindings description for Samsung S3C2410 and
> compatible NAND flash controller.
>
> Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
> ---
> .../devicetree/bindings/mtd/samsung-s3c2410.txt | 57 ++++++++++++++++++++++
> 1 file changed, 57 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mtd/samsung-s3c2410.txt
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
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