Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] PM / AVS: rockchip-io: make the log more consistent
From: Heiko Stuebner @ 2016-10-10 20:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476103462-7559-1-git-send-email-shawn.lin@rock-chips.com>

Am Montag, 10. Oktober 2016, 20:44:22 CEST schrieb Shawn Lin:
> When testing SD hotplug automatically, I got bunch of
> useless log like this:
> 
> [  588.357838] mmc0: card 0007 removed
> [  589.492664] rockchip-iodomain ff770000.syscon:io-domains: Setting to
> 3300000 done [  589.500698] vccio_sd: ramp_delay not set
> [  589.504817] rockchip-iodomain ff770000.syscon:io-domains: Setting to
> 3300000 done [  589.669705] rockchip-iodomain ff770000.syscon:io-domains:
> Setting to 3300000 done [  589.677593] vccio_sd: ramp_delay not set
> [  589.681581] rockchip-iodomain ff770000.syscon:io-domains: Setting to
> 1800000 done [  590.032820] dwmmc_rockchip ff0c0000.dwmmc: Successfully
> tuned phase to 140 [  590.039725] mmc0: new ultra high speed SDR50 SDHC
> card at address 0007 [  590.046641] mmcblk0: mmc0:0007 SD32G 29.3 GiB
> [  590.052163]  mmcblk0: p1
> 
> Moreover the code is intent to print the 'uV' for debug but
> later print it using dev_info. It looks more like to me that
> it should be the real intention of the code. Anyway, let's
> mark this verbose log as debug message.
> 
> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>

reducing the amount of logs, especially for information not generally needed 
looks sane

Reviewed-by: Heiko Stuebner <heiko@sntech.de>

> ---
> 
>  drivers/power/avs/rockchip-io-domain.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/power/avs/rockchip-io-domain.c
> b/drivers/power/avs/rockchip-io-domain.c index 01b6d3f..56bce19 100644
> --- a/drivers/power/avs/rockchip-io-domain.c
> +++ b/drivers/power/avs/rockchip-io-domain.c
> @@ -143,7 +143,7 @@ static int rockchip_iodomain_notify(struct
> notifier_block *nb, if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
>  		return NOTIFY_BAD;
> 
> -	dev_info(supply->iod->dev, "Setting to %d done\n", uV);
> +	dev_dbg(supply->iod->dev, "Setting to %d done\n", uV);
>  	return NOTIFY_OK;
>  }

^ permalink raw reply

* [PATCH 1/1 v8] ARM: imx: Added perf functionality to mmdc driver
From: Zhi Li @ 2016-10-10 20:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAHrpEqQE5w_+4tn1SnFs8rQnWXRb86LDMSGxE7xCUDE=8WnbyQ@mail.gmail.com>

On Mon, Sep 26, 2016 at 11:40 AM, Zhi Li <lznuaa@gmail.com> wrote:
> On Mon, Sep 19, 2016 at 12:57 PM, Frank Li <Frank.Li@nxp.com> wrote:
>> From: Zhengyu Shen <zhengyu.shen@nxp.com>
>>
>> MMDC is a multi-mode DDR controller that supports DDR3/DDR3L x16/x32/x64
>> and LPDDR2 two channel x16/x32 memory types. MMDC is configurable, high
>> performance, and optimized. MMDC is present on i.MX6 Quad and i.MX6
>> QuadPlus devices, but this driver only supports i.MX6 Quad at the moment.
>> MMDC provides registers for performance counters which read via this
>> driver to help debug memory throughput and similar issues.
>>
>> $ perf stat -a -e mmdc/busy-cycles/,mmdc/read-accesses/,mmdc/read-bytes/,mmdc/total-cycles/,mmdc/write-accesses/,mmdc/write-bytes/ dd if=/dev/zero of=/dev/null bs=1M count=5000
>> Performance counter stats for 'dd if=/dev/zero of=/dev/null bs=1M count=5000':
>>
>>          898021787      mmdc/busy-cycles/
>>           14819600      mmdc/read-accesses/
>>             471.30 MB   mmdc/read-bytes/
>>         2815419216      mmdc/total-cycles/
>>           13367354      mmdc/write-accesses/
>>             427.76 MB   mmdc/write-bytes/
>>
>>        5.334757334 seconds time elapsed
>>
>> Signed-off-by: Zhengyu Shen <zhengyu.shen@nxp.com>
>> Signed-off-by: Frank Li <frank.li@nxp.com>
>> ---
>
> Mark:
>         Any additional comments for this version?
>

Shawn:
           No any new comment for more than 2 weeks.
           Did you plan accept this patch?

> best regards
> Frank Li
>
>> Changes from v7 to v8
>>     fix a group event check problem, should be slibling.
>>
>> Changes from v6 to v7
>>     use mmdc_pmu prefix
>>     remove unnecessary check
>>     improve group event check according to mark's feedback.
>>     check pmu_mmdc->mmdc_events[cfg] at event_add
>>     only check == 0 at event_del
>>
>> Changes from v5 to v6
>>     Improve group event error handle
>>
>> Changes from v4 to v5
>>     Remove mmdc_pmu:irq
>>     remove static variable cpuhp_mmdc_pmu
>>     remove spin_lock
>>     check is_sampling_event(event)
>>     remove unnecessary cast
>>     use hw_perf_event::prev_count
>>
>> Changes from v3 to v4:
>>     Tested and fixed crash relating to removing events with perf fuzzer
>>     Adjusted formatting
>>     Moved all perf event code under CONFIG_PERF_EVENTS
>>         Switched cpuhp_setup_state to cpuhp_setup_state_nocalls
>>
>> Changes from v2 to v3:
>>     Use WARN_ONCE instead of returning generic error values
>>     Replace CPU Notifiers with newer state machine hotplug
>>     Added additional checks on event_init for grouping and sampling
>>     Remove useless mmdc_enable_profiling function
>>     Added comments
>>     Moved start index of events from 0x01 to 0x00
>>     Added a counter to pmu_mmdc to only stop hrtimer after all events are finished
>>     Replace readl_relaxed and writel_relaxed with readl and writel
>>     Removed duplicate update function
>>     Used devm_kasprintf when naming mmdcs probed
>>
>> Changes from v1 to v2:
>>     Added cpumask and migration handling support to driver
>>     Validated event during event_init
>>     Added code to properly stop counters
>>     Used perf_invalid_context instead of perf_sw_context
>>     Added hrtimer to poll for overflow
>>     Added better description
>>     Added support for multiple mmdcs
>>
>>  arch/arm/mach-imx/mmdc.c | 459 ++++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 457 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
>> index db9621c..d82d14c 100644
>> --- a/arch/arm/mach-imx/mmdc.c
>> +++ b/arch/arm/mach-imx/mmdc.c
>> @@ -1,5 +1,5 @@
>>  /*
>> - * Copyright 2011 Freescale Semiconductor, Inc.
>> + * Copyright 2011,2016 Freescale Semiconductor, Inc.
>>   * Copyright 2011 Linaro Ltd.
>>   *
>>   * The code contained herein is licensed under the GNU General Public
>> @@ -10,12 +10,16 @@
>>   * http://www.gnu.org/copyleft/gpl.html
>>   */
>>
>> +#include <linux/hrtimer.h>
>>  #include <linux/init.h>
>> +#include <linux/interrupt.h>
>>  #include <linux/io.h>
>>  #include <linux/module.h>
>>  #include <linux/of.h>
>>  #include <linux/of_address.h>
>>  #include <linux/of_device.h>
>> +#include <linux/perf_event.h>
>> +#include <linux/slab.h>
>>
>>  #include "common.h"
>>
>> @@ -27,8 +31,458 @@
>>  #define BM_MMDC_MDMISC_DDR_TYPE        0x18
>>  #define BP_MMDC_MDMISC_DDR_TYPE        0x3
>>
>> +#define TOTAL_CYCLES           0x0
>> +#define BUSY_CYCLES            0x1
>> +#define READ_ACCESSES          0x2
>> +#define WRITE_ACCESSES         0x3
>> +#define READ_BYTES             0x4
>> +#define WRITE_BYTES            0x5
>> +
>> +/* Enables, resets, freezes, overflow profiling*/
>> +#define DBG_DIS                        0x0
>> +#define DBG_EN                 0x1
>> +#define DBG_RST                        0x2
>> +#define PRF_FRZ                        0x4
>> +#define CYC_OVF                        0x8
>> +
>> +#define MMDC_MADPCR0   0x410
>> +#define MMDC_MADPSR0   0x418
>> +#define MMDC_MADPSR1   0x41C
>> +#define MMDC_MADPSR2   0x420
>> +#define MMDC_MADPSR3   0x424
>> +#define MMDC_MADPSR4   0x428
>> +#define MMDC_MADPSR5   0x42C
>> +
>> +#define MMDC_NUM_COUNTERS      6
>> +
>> +#define to_mmdc_pmu(p) container_of(p, struct mmdc_pmu, pmu)
>> +
>>  static int ddr_type;
>>
>> +#ifdef CONFIG_PERF_EVENTS
>> +
>> +static DEFINE_IDA(mmdc_ida);
>> +
>> +PMU_EVENT_ATTR_STRING(total-cycles, mmdc_pmu_total_cycles, "event=0x00")
>> +PMU_EVENT_ATTR_STRING(busy-cycles, mmdc_pmu_busy_cycles, "event=0x01")
>> +PMU_EVENT_ATTR_STRING(read-accesses, mmdc_pmu_read_accesses, "event=0x02")
>> +PMU_EVENT_ATTR_STRING(write-accesses, mmdc_pmu_write_accesses, "config=0x03")
>> +PMU_EVENT_ATTR_STRING(read-bytes, mmdc_pmu_read_bytes, "event=0x04")
>> +PMU_EVENT_ATTR_STRING(read-bytes.unit, mmdc_pmu_read_bytes_unit, "MB");
>> +PMU_EVENT_ATTR_STRING(read-bytes.scale, mmdc_pmu_read_bytes_scale, "0.000001");
>> +PMU_EVENT_ATTR_STRING(write-bytes, mmdc_pmu_write_bytes, "event=0x05")
>> +PMU_EVENT_ATTR_STRING(write-bytes.unit, mmdc_pmu_write_bytes_unit, "MB");
>> +PMU_EVENT_ATTR_STRING(write-bytes.scale, mmdc_pmu_write_bytes_scale, "0.000001");
>> +
>> +struct mmdc_pmu {
>> +       struct pmu pmu;
>> +       void __iomem *mmdc_base;
>> +       cpumask_t cpu;
>> +       struct hrtimer hrtimer;
>> +       unsigned int active_events;
>> +       struct device *dev;
>> +       struct perf_event *mmdc_events[MMDC_NUM_COUNTERS];
>> +       struct hlist_node node;
>> +};
>> +
>> +/*
>> + * Polling period is set to one second, overflow of total-cycles (the fastest
>> + * increasing counter) takes ten seconds so one second is safe
>> + */
>> +static unsigned int mmdc_pmu_poll_period_us = 1000000;
>> +
>> +module_param_named(pmu_pmu_poll_period_us, mmdc_pmu_poll_period_us, uint,
>> +               S_IRUGO | S_IWUSR);
>> +
>> +static ktime_t mmdc_pmu_timer_period(void)
>> +{
>> +       return ns_to_ktime((u64)mmdc_pmu_poll_period_us * 1000);
>> +}
>> +
>> +static ssize_t mmdc_pmu_cpumask_show(struct device *dev,
>> +               struct device_attribute *attr, char *buf)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc = dev_get_drvdata(dev);
>> +
>> +       return cpumap_print_to_pagebuf(true, buf, &pmu_mmdc->cpu);
>> +}
>> +
>> +static struct device_attribute mmdc_pmu_cpumask_attr =
>> +       __ATTR(cpumask, S_IRUGO, mmdc_pmu_cpumask_show, NULL);
>> +
>> +static struct attribute *mmdc_pmu_cpumask_attrs[] = {
>> +       &mmdc_pmu_cpumask_attr.attr,
>> +       NULL,
>> +};
>> +
>> +static struct attribute_group mmdc_pmu_cpumask_attr_group = {
>> +       .attrs = mmdc_pmu_cpumask_attrs,
>> +};
>> +
>> +static struct attribute *mmdc_pmu_events_attrs[] = {
>> +       &mmdc_pmu_total_cycles.attr.attr,
>> +       &mmdc_pmu_busy_cycles.attr.attr,
>> +       &mmdc_pmu_read_accesses.attr.attr,
>> +       &mmdc_pmu_write_accesses.attr.attr,
>> +       &mmdc_pmu_read_bytes.attr.attr,
>> +       &mmdc_pmu_read_bytes_unit.attr.attr,
>> +       &mmdc_pmu_read_bytes_scale.attr.attr,
>> +       &mmdc_pmu_write_bytes.attr.attr,
>> +       &mmdc_pmu_write_bytes_unit.attr.attr,
>> +       &mmdc_pmu_write_bytes_scale.attr.attr,
>> +       NULL,
>> +};
>> +
>> +static struct attribute_group mmdc_pmu_events_attr_group = {
>> +       .name = "events",
>> +       .attrs = mmdc_pmu_events_attrs,
>> +};
>> +
>> +PMU_FORMAT_ATTR(event, "config:0-63");
>> +static struct attribute *mmdc_pmu_format_attrs[] = {
>> +       &format_attr_event.attr,
>> +       NULL,
>> +};
>> +
>> +static struct attribute_group mmdc_pmu_format_attr_group = {
>> +       .name = "format",
>> +       .attrs = mmdc_pmu_format_attrs,
>> +};
>> +
>> +static const struct attribute_group *attr_groups[] = {
>> +       &mmdc_pmu_events_attr_group,
>> +       &mmdc_pmu_format_attr_group,
>> +       &mmdc_pmu_cpumask_attr_group,
>> +       NULL,
>> +};
>> +
>> +static u32 mmdc_pmu_read_counter(struct mmdc_pmu *pmu_mmdc, int cfg)
>> +{
>> +       void __iomem *mmdc_base, *reg;
>> +
>> +       mmdc_base = pmu_mmdc->mmdc_base;
>> +
>> +       switch (cfg) {
>> +       case TOTAL_CYCLES:
>> +               reg = mmdc_base + MMDC_MADPSR0;
>> +               break;
>> +       case BUSY_CYCLES:
>> +               reg = mmdc_base + MMDC_MADPSR1;
>> +               break;
>> +       case READ_ACCESSES:
>> +               reg = mmdc_base + MMDC_MADPSR2;
>> +               break;
>> +       case WRITE_ACCESSES:
>> +               reg = mmdc_base + MMDC_MADPSR3;
>> +               break;
>> +       case READ_BYTES:
>> +               reg = mmdc_base + MMDC_MADPSR4;
>> +               break;
>> +       case WRITE_BYTES:
>> +               reg = mmdc_base + MMDC_MADPSR5;
>> +               break;
>> +       default:
>> +               return WARN_ONCE(1,
>> +                       "invalid configuration %d for mmdc counter", cfg);
>> +       }
>> +       return readl(reg);
>> +}
>> +
>> +static int mmdc_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc = hlist_entry_safe(node, struct mmdc_pmu, node);
>> +       int target;
>> +
>> +       if (!cpumask_test_and_clear_cpu(cpu, &pmu_mmdc->cpu))
>> +               return 0;
>> +
>> +       target = cpumask_any_but(cpu_online_mask, cpu);
>> +       if (target >= nr_cpu_ids)
>> +               return 0;
>> +
>> +       perf_pmu_migrate_context(&pmu_mmdc->pmu, cpu, target);
>> +       cpumask_set_cpu(target, &pmu_mmdc->cpu);
>> +
>> +       return 0;
>> +}
>> +
>> +static bool mmdc_pmu_group_event_is_valid(struct perf_event *event,
>> +                                         struct pmu *pmu,
>> +                                         unsigned long *used_counters)
>> +{
>> +       int cfg = event->attr.config;
>> +
>> +       if (is_software_event(event))
>> +               return true;
>> +
>> +       if (event->pmu != pmu)
>> +               return false;
>> +
>> +       return !test_and_set_bit(cfg, used_counters);
>> +}
>> +
>> +/*
>> + * Each event has a single fixed-purpose counter, so we can only have a
>> + * single active event for each at any point in time. Here we just check
>> + * for duplicates, and rely on mmdc_pmu_event_init to verify that the HW
>> + * event numbers are valid.
>> + */
>> +static bool mmdc_pmu_group_is_valid(struct perf_event *event)
>> +{
>> +       struct pmu *pmu = event->pmu;
>> +       struct perf_event *leader = event->group_leader;
>> +       struct perf_event *sibling;
>> +       unsigned long counter_mask = 0;
>> +
>> +       set_bit(leader->attr.config, &counter_mask);
>> +
>> +       if (event != leader) {
>> +               if (!mmdc_pmu_group_event_is_valid(event, pmu, &counter_mask))
>> +                       return false;
>> +       }
>> +
>> +       list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
>> +               if (!mmdc_pmu_group_event_is_valid(sibling, pmu, &counter_mask))
>> +                       return false;
>> +       }
>> +
>> +       return true;
>> +}
>> +
>> +static int mmdc_pmu_event_init(struct perf_event *event)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
>> +       int cfg = event->attr.config;
>> +
>> +       if (event->attr.type != event->pmu->type)
>> +               return -ENOENT;
>> +
>> +       if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
>> +               return -EOPNOTSUPP;
>> +
>> +       if (event->cpu < 0) {
>> +               dev_warn(pmu_mmdc->dev, "Can't provide per-task data!\n");
>> +               return -EOPNOTSUPP;
>> +       }
>> +
>> +       if (event->attr.exclude_user            ||
>> +                       event->attr.exclude_kernel      ||
>> +                       event->attr.exclude_hv          ||
>> +                       event->attr.exclude_idle        ||
>> +                       event->attr.exclude_host        ||
>> +                       event->attr.exclude_guest       ||
>> +                       event->attr.sample_period)
>> +               return -EINVAL;
>> +
>> +       if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
>> +               return -EINVAL;
>> +
>> +       if (!mmdc_pmu_group_is_valid(event))
>> +               return -EINVAL;
>> +
>> +       event->cpu = cpumask_first(&pmu_mmdc->cpu);
>> +       return 0;
>> +}
>> +
>> +static void mmdc_pmu_event_update(struct perf_event *event)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
>> +       struct hw_perf_event *hwc = &event->hw;
>> +       u64 delta, prev_raw_count, new_raw_count;
>> +
>> +       do {
>> +               prev_raw_count = local64_read(&hwc->prev_count);
>> +               new_raw_count = mmdc_pmu_read_counter(pmu_mmdc,
>> +                                                     event->attr.config);
>> +       } while (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
>> +               new_raw_count) != prev_raw_count);
>> +
>> +       delta = (new_raw_count - prev_raw_count) & 0xFFFFFFFF;
>> +
>> +       local64_add(delta, &event->count);
>> +}
>> +
>> +static void mmdc_pmu_event_start(struct perf_event *event, int flags)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
>> +       struct hw_perf_event *hwc = &event->hw;
>> +       void __iomem *mmdc_base, *reg;
>> +
>> +       mmdc_base = pmu_mmdc->mmdc_base;
>> +       reg = mmdc_base + MMDC_MADPCR0;
>> +
>> +       /*
>> +        * hrtimer is required because mmdc does not provide an interrupt so
>> +        * polling is necessary
>> +        */
>> +       hrtimer_start(&pmu_mmdc->hrtimer, mmdc_pmu_timer_period(),
>> +                       HRTIMER_MODE_REL_PINNED);
>> +
>> +       local64_set(&hwc->prev_count, 0);
>> +
>> +       writel(DBG_RST, reg);
>> +       writel(DBG_EN, reg);
>> +}
>> +
>> +static int mmdc_pmu_event_add(struct perf_event *event, int flags)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
>> +       struct hw_perf_event *hwc = &event->hw;
>> +
>> +       int cfg = event->attr.config;
>> +
>> +       if (flags & PERF_EF_START)
>> +               mmdc_pmu_event_start(event, flags);
>> +
>> +       if (pmu_mmdc->mmdc_events[cfg] != NULL)
>> +               return -EAGAIN;
>> +
>> +       pmu_mmdc->mmdc_events[cfg] = event;
>> +       pmu_mmdc->active_events++;
>> +
>> +       local64_set(&hwc->prev_count, mmdc_pmu_read_counter(pmu_mmdc, cfg));
>> +
>> +       return 0;
>> +}
>> +
>> +static void mmdc_pmu_event_stop(struct perf_event *event, int flags)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
>> +       void __iomem *mmdc_base, *reg;
>> +
>> +       mmdc_base = pmu_mmdc->mmdc_base;
>> +       reg = mmdc_base + MMDC_MADPCR0;
>> +
>> +       writel(PRF_FRZ, reg);
>> +       mmdc_pmu_event_update(event);
>> +}
>> +
>> +static void mmdc_pmu_event_del(struct perf_event *event, int flags)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
>> +       int cfg = event->attr.config;
>> +
>> +       pmu_mmdc->mmdc_events[cfg] = NULL;
>> +       pmu_mmdc->active_events--;
>> +
>> +       if (pmu_mmdc->active_events == 0)
>> +               hrtimer_cancel(&pmu_mmdc->hrtimer);
>> +
>> +       mmdc_pmu_event_stop(event, PERF_EF_UPDATE);
>> +}
>> +
>> +static void mmdc_pmu_overflow_handler(struct mmdc_pmu *pmu_mmdc)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < MMDC_NUM_COUNTERS; i++) {
>> +               struct perf_event *event = pmu_mmdc->mmdc_events[i];
>> +
>> +               if (event)
>> +                       mmdc_pmu_event_update(event);
>> +       }
>> +}
>> +
>> +static enum hrtimer_restart mmdc_pmu_timer_handler(struct hrtimer *hrtimer)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc = container_of(hrtimer, struct mmdc_pmu,
>> +                       hrtimer);
>> +
>> +       mmdc_pmu_overflow_handler(pmu_mmdc);
>> +       hrtimer_forward_now(hrtimer, mmdc_pmu_timer_period());
>> +
>> +       return HRTIMER_RESTART;
>> +}
>> +
>> +static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
>> +               void __iomem *mmdc_base, struct device *dev)
>> +{
>> +       int mmdc_num;
>> +
>> +       *pmu_mmdc = (struct mmdc_pmu) {
>> +               .pmu = (struct pmu) {
>> +                       .task_ctx_nr    = perf_invalid_context,
>> +                       .attr_groups    = attr_groups,
>> +                       .event_init     = mmdc_pmu_event_init,
>> +                       .add            = mmdc_pmu_event_add,
>> +                       .del            = mmdc_pmu_event_del,
>> +                       .start          = mmdc_pmu_event_start,
>> +                       .stop           = mmdc_pmu_event_stop,
>> +                       .read           = mmdc_pmu_event_update,
>> +               },
>> +               .mmdc_base = mmdc_base,
>> +               .dev = dev,
>> +               .active_events = 0,
>> +       };
>> +
>> +       mmdc_num = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL);
>> +
>> +       return mmdc_num;
>> +}
>> +
>> +static int imx_mmdc_remove(struct platform_device *pdev)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev);
>> +
>> +       perf_pmu_unregister(&pmu_mmdc->pmu);
>> +       cpuhp_remove_state_nocalls(CPUHP_ONLINE);
>> +       kfree(pmu_mmdc);
>> +       return 0;
>> +}
>> +
>> +static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_base)
>> +{
>> +       struct mmdc_pmu *pmu_mmdc;
>> +       char *name;
>> +       int mmdc_num;
>> +       int ret;
>> +
>> +       pmu_mmdc = kzalloc(sizeof(*pmu_mmdc), GFP_KERNEL);
>> +       if (!pmu_mmdc) {
>> +               pr_err("failed to allocate PMU device!\n");
>> +               return -ENOMEM;
>> +       }
>> +
>> +       mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev);
>> +       if (mmdc_num == 0)
>> +               name = "mmdc";
>> +       else
>> +               name = devm_kasprintf(&pdev->dev,
>> +                               GFP_KERNEL, "mmdc%d", mmdc_num);
>> +
>> +       hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC,
>> +                       HRTIMER_MODE_REL);
>> +       pmu_mmdc->hrtimer.function = mmdc_pmu_timer_handler;
>> +
>> +       cpuhp_state_add_instance_nocalls(CPUHP_ONLINE,
>> +                                        &pmu_mmdc->node);
>> +       cpumask_set_cpu(smp_processor_id(), &pmu_mmdc->cpu);
>> +       ret = cpuhp_setup_state_multi(CPUHP_AP_NOTIFY_ONLINE,
>> +                                     "MMDC_ONLINE", NULL,
>> +                                     mmdc_pmu_offline_cpu);
>> +       if (ret) {
>> +               pr_err("cpuhp_setup_state_multi failure\n");
>> +               goto pmu_register_err;
>> +       }
>> +
>> +       ret = perf_pmu_register(&(pmu_mmdc->pmu), name, -1);
>> +       platform_set_drvdata(pdev, pmu_mmdc);
>> +       if (ret)
>> +               goto pmu_register_err;
>> +       return 0;
>> +
>> +pmu_register_err:
>> +       pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret);
>> +       hrtimer_cancel(&pmu_mmdc->hrtimer);
>> +       kfree(pmu_mmdc);
>> +       return ret;
>> +}
>> +
>> +#else
>> +#define imx_mmdc_remove NULL
>> +#define imx_mmdc_perf_init(pdev, mmdc_base) 0
>> +#endif
>> +
>>  static int imx_mmdc_probe(struct platform_device *pdev)
>>  {
>>         struct device_node *np = pdev->dev.of_node;
>> @@ -62,7 +516,7 @@ static int imx_mmdc_probe(struct platform_device *pdev)
>>                 return -EBUSY;
>>         }
>>
>> -       return 0;
>> +       return imx_mmdc_perf_init(pdev, mmdc_base);
>>  }
>>
>>  int imx_mmdc_get_ddr_type(void)
>> @@ -81,6 +535,7 @@ static struct platform_driver imx_mmdc_driver = {
>>                 .of_match_table = imx_mmdc_dt_ids,
>>         },
>>         .probe          = imx_mmdc_probe,
>> +       .remove         = imx_mmdc_remove,
>>  };
>>
>>  static int __init imx_mmdc_init(void)
>> --
>> 2.5.2
>>

^ permalink raw reply

* [PATCH v3 3/6] pwm: imx: support output polarity inversion
From: Stefan Agner @ 2016-10-10 21:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161007151129.6043-4-bhuvanchandra.dv@toradex.com>

On 2016-10-07 08:11, Bhuvanchandra DV wrote:
> From: Lothar Wassmann <LW@KARO-electronics.de>
> 
> The i.MX pwm unit on i.MX27 and newer SoCs provides a configurable output
> polarity. This patch adds support to utilize this feature where available.
> 
> Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de>
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
> Acked-by: Shawn Guo <shawn.guo@linaro.org>
> Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  Documentation/devicetree/bindings/pwm/imx-pwm.txt |  6 +--
>  drivers/pwm/pwm-imx.c                             | 51 +++++++++++++++++++++--
>  2 files changed, 51 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.txt
> b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
> index e00c2e9..c61bdf8 100644
> --- a/Documentation/devicetree/bindings/pwm/imx-pwm.txt
> +++ b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
> @@ -6,8 +6,8 @@ Required properties:
>    - "fsl,imx1-pwm" for PWM compatible with the one integrated on i.MX1
>    - "fsl,imx27-pwm" for PWM compatible with the one integrated on i.MX27
>  - reg: physical base address and length of the controller's registers
> -- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
> -  the cells format.
> +- #pwm-cells: 2 for i.MX1 and 3 for i.MX27 and newer SoCs. See pwm.txt
> +  in this directory for a description of the cells format.
>  - clocks : Clock specifiers for both ipg and per clocks.
>  - clock-names : Clock names should include both "ipg" and "per"
>  See the clock consumer binding,
> @@ -17,7 +17,7 @@ See the clock consumer binding,
>  Example:
>  
>  pwm1: pwm at 53fb4000 {
> -	#pwm-cells = <2>;
> +	#pwm-cells = <3>;
>  	compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
>  	reg = <0x53fb4000 0x4000>;
>  	clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
> diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
> index d600fd5..c37d223 100644
> --- a/drivers/pwm/pwm-imx.c
> +++ b/drivers/pwm/pwm-imx.c
> @@ -38,6 +38,7 @@
>  #define MX3_PWMCR_DOZEEN		(1 << 24)
>  #define MX3_PWMCR_WAITEN		(1 << 23)
>  #define MX3_PWMCR_DBGEN			(1 << 22)
> +#define MX3_PWMCR_POUTC			(1 << 18)
>  #define MX3_PWMCR_CLKSRC_IPG_HIGH	(2 << 16)
>  #define MX3_PWMCR_CLKSRC_IPG		(1 << 16)
>  #define MX3_PWMCR_SWR			(1 << 3)
> @@ -180,6 +181,9 @@ static int imx_pwm_config_v2(struct pwm_chip *chip,
>  	if (enable)
>  		cr |= MX3_PWMCR_EN;
>  
> +	if (pwm->args.polarity == PWM_POLARITY_INVERSED)
> +		cr |= MX3_PWMCR_POUTC;
> +

This seems wrong to me, the config callback is meant for period/duty
cycle only. The set_polarity callback should get called in case a
different polarity is requested.


>  	writel(cr, imx->mmio_base + MX3_PWMCR);
>  
>  	return 0;
> @@ -240,27 +244,62 @@ static void imx_pwm_disable(struct pwm_chip
> *chip, struct pwm_device *pwm)
>  	clk_disable_unprepare(imx->clk_per);
>  }
>  
> -static struct pwm_ops imx_pwm_ops = {
> +static int imx_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
> +				enum pwm_polarity polarity)
> +{
> +	struct imx_chip *imx = to_imx_chip(chip);
> +	u32 val;
> +
> +	if (polarity == pwm->args.polarity)
> +		return 0;

I don't think that this is right. Today, pwm_apply_args (in
include/linux/pwm.h) copies the polarity from args to state.polarity,
which is then passed as polarity argument to this function. So this will
always return 0 afaict.

I would just drop that.

There is probably one little problem in the current state of affairs: If
the bootloader makes use of a PWM channel with inverted state, then the
kernel would not know about that and currently assume a wrong initial
state... I guess at one point in time we should implement the state
retrieval callback and move to the new atomic PWM API, which would mean
to implement apply callback.

--
Stefan


> +
> +	val = readl(imx->mmio_base + MX3_PWMCR);
> +
> +	if (polarity == PWM_POLARITY_INVERSED)
> +		val |= MX3_PWMCR_POUTC;
> +	else
> +		val &= ~MX3_PWMCR_POUTC;
> +
> +	writel(val, imx->mmio_base + MX3_PWMCR);
> +
> +	dev_dbg(imx->chip.dev, "%s: polarity set to %s\n", __func__,
> +		polarity == PWM_POLARITY_INVERSED ? "inverted" : "normal");
> +
> +	return 0;
> +}
> +
> +static struct pwm_ops imx_pwm_ops_v1 = {
>  	.enable = imx_pwm_enable,
>  	.disable = imx_pwm_disable,
>  	.config = imx_pwm_config,
>  	.owner = THIS_MODULE,
>  };
>  
> +static struct pwm_ops imx_pwm_ops_v2 = {
> +	.enable = imx_pwm_enable,
> +	.disable = imx_pwm_disable,
> +	.set_polarity = imx_pwm_set_polarity,
> +	.config = imx_pwm_config,
> +	.owner = THIS_MODULE,
> +};
> +
>  struct imx_pwm_data {
>  	int (*config)(struct pwm_chip *chip,
>  		struct pwm_device *pwm, int duty_ns, int period_ns);
>  	void (*set_enable)(struct pwm_chip *chip, bool enable);
> +	struct pwm_ops *pwm_ops;
>  };
>  
>  static struct imx_pwm_data imx_pwm_data_v1 = {
>  	.config = imx_pwm_config_v1,
>  	.set_enable = imx_pwm_set_enable_v1,
> +	.pwm_ops = &imx_pwm_ops_v1,
>  };
>  
>  static struct imx_pwm_data imx_pwm_data_v2 = {
>  	.config = imx_pwm_config_v2,
>  	.set_enable = imx_pwm_set_enable_v2,
> +	.pwm_ops = &imx_pwm_ops_v2,
>  };
>  
>  static const struct of_device_id imx_pwm_dt_ids[] = {
> @@ -282,6 +321,8 @@ static int imx_pwm_probe(struct platform_device *pdev)
>  	if (!of_id)
>  		return -ENODEV;
>  
> +	data = of_id->data;
> +
>  	imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL);
>  	if (imx == NULL)
>  		return -ENOMEM;
> @@ -300,18 +341,22 @@ static int imx_pwm_probe(struct platform_device *pdev)
>  		return PTR_ERR(imx->clk_ipg);
>  	}
>  
> -	imx->chip.ops = &imx_pwm_ops;
> +	imx->chip.ops = data->pwm_ops;
>  	imx->chip.dev = &pdev->dev;
>  	imx->chip.base = -1;
>  	imx->chip.npwm = 1;
>  	imx->chip.can_sleep = true;
> +	if (data->pwm_ops->set_polarity) {
> +		dev_dbg(&pdev->dev, "PWM supports output inversion\n");
> +		imx->chip.of_xlate = of_pwm_xlate_with_flags;
> +		imx->chip.of_pwm_n_cells = 3;
> +	}
>  
>  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	imx->mmio_base = devm_ioremap_resource(&pdev->dev, r);
>  	if (IS_ERR(imx->mmio_base))
>  		return PTR_ERR(imx->mmio_base);
>  
> -	data = of_id->data;
>  	imx->config = data->config;
>  	imx->set_enable = data->set_enable;

^ permalink raw reply

* [PATCH 1/2] arm64: Cleanup kexec Makefile
From: Geoff Levand @ 2016-10-10 21:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1476134309.git.geoff@infradead.org>

Put files in alphabetical order, reformat whitspace.

Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 kexec/arch/arm64/Makefile | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile
index 37414dc..d729df8 100644
--- a/kexec/arch/arm64/Makefile
+++ b/kexec/arch/arm64/Makefile
@@ -1,17 +1,18 @@
 
 arm64_FS2DT += kexec/fs2dt.c
-arm64_FS2DT_INCLUDE += -include $(srcdir)/kexec/arch/arm64/kexec-arm64.h \
-	-include $(srcdir)/kexec/arch/arm64/crashdump-arm64.h
+arm64_FS2DT_INCLUDE += \
+	-include $(srcdir)/kexec/arch/arm64/crashdump-arm64.h \
+	-include $(srcdir)/kexec/arch/arm64/kexec-arm64.h
 
 arm64_DT_OPS += kexec/dt-ops.c
 
 arm64_CPPFLAGS += -I $(srcdir)/kexec/
 
 arm64_KEXEC_SRCS += \
+	kexec/arch/arm64/crashdump-arm64.c \
 	kexec/arch/arm64/kexec-arm64.c \
-	kexec/arch/arm64/kexec-image-arm64.c \
 	kexec/arch/arm64/kexec-elf-arm64.c \
-	kexec/arch/arm64/crashdump-arm64.c
+	kexec/arch/arm64/kexec-image-arm64.c
 
 arm64_ARCH_REUSE_INITRD =
 arm64_ADD_SEGMENT =
@@ -19,9 +20,9 @@ arm64_VIRT_TO_PHYS =
 arm64_PHYS_TO_VIRT =
 
 dist += $(arm64_KEXEC_SRCS) \
-	kexec/arch/arm64/Makefile \
+	kexec/arch/arm64/crashdump-arm64.h \
 	kexec/arch/arm64/kexec-arm64.h \
-	kexec/arch/arm64/crashdump-arm64.h
+	kexec/arch/arm64/Makefile
 
 ifdef HAVE_LIBFDT
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH 0/2] arm64 kexec-tools fixups
From: Geoff Levand @ 2016-10-10 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Simon,

Fixes for 'make tarball'.  Please apply.

-Geoff

The following changes since commit 6e8804f9ca67bee65aedd5e1cdf504737ab5c7ed:

  multiboot: Use the "reserved" type for non-ram zones (2016-10-07 11:54:44 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geoff/kexec-tools.git for-merge-arm64-dist

for you to fetch changes up to 3552a3e85a910688d932535549b35354a54927ad:

  arm64: Add missing kexec dist files (2016-10-10 14:15:21 -0700)

----------------------------------------------------------------
Geoff Levand (2):
      arm64: Cleanup kexec Makefile
      arm64: Add missing kexec dist files

 kexec/arch/arm64/Makefile | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [PATCH 2/2] arm64: Add missing kexec dist files
From: Geoff Levand @ 2016-10-10 21:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1476134309.git.geoff@infradead.org>

Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 kexec/arch/arm64/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile
index d729df8..74b677f 100644
--- a/kexec/arch/arm64/Makefile
+++ b/kexec/arch/arm64/Makefile
@@ -20,7 +20,9 @@ arm64_VIRT_TO_PHYS =
 arm64_PHYS_TO_VIRT =
 
 dist += $(arm64_KEXEC_SRCS) \
+	kexec/arch/arm64/include/arch/options.h \
 	kexec/arch/arm64/crashdump-arm64.h \
+	kexec/arch/arm64/image-header.h \
 	kexec/arch/arm64/kexec-arm64.h \
 	kexec/arch/arm64/Makefile
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 3/8] PM / Domains: Allow domain power states to be read from DT
From: Ulf Hansson @ 2016-10-10 21:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161010150301.GA44885@linaro.org>

[...]

>>> +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.

Ahh, right. So let's keep it as is!

[...]

Kind regards
Uffe

^ permalink raw reply

* [PATCH 5/10] dt: bindings: Add bindings for Marvell Xenon SD Host Controller
From: Rob Herring @ 2016-10-10 21:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <fc0ca2b3140287cbccf5c176a12b7dce25d06a47.1475853198.git-series.gregory.clement@free-electrons.com>

On Fri, Oct 07, 2016 at 05:22:51PM +0200, Gregory CLEMENT wrote:
> From: Ziji Hu <huziji@marvell.com>
> 
> Marvell Xenon SDHC can support eMMC/SD/SDIO.
> Add Xenon-specific properties.
> Also add properties for Xenon PHY setting.
> 
> Signed-off-by: Hu Ziji <huziji@marvell.com>
> Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  Documentation/devicetree/bindings/mmc/marvell,sdhci-xenon.txt | 164 +++++++-
>  MAINTAINERS                                                   |   1 +-
>  2 files changed, 165 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/mmc/marvell,sdhci-xenon.txt
> 
> diff --git a/Documentation/devicetree/bindings/mmc/marvell,sdhci-xenon.txt b/Documentation/devicetree/bindings/mmc/marvell,sdhci-xenon.txt
> new file mode 100644
> index 000000000000..8b25ad28ebbd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/marvell,sdhci-xenon.txt
> @@ -0,0 +1,164 @@
> +Marvell's Xenon SDHCI Controller device tree bindings
> +This file documents differences between the core mmc properties
> +described by mmc.txt and the properties used by the Xenon implementation.
> +
> +A single Xenon IP can support multiple slots.
> +Each slot acts as an independent SDHC. It owns independent resources, such
> +as register sets clock and PHY.

Is the phy really part of the same block?

> +Each slot should have an independent device tree node.
> +
> +Required Properties:
> +- compatible: should be "marvell,sdhci-xenon" or "marvell,armada-3700-sdhci".

Perhaps some consistent ordering (w/ -sdhci on the end).

> +
> +- Input Clock Name

Your formatting of properties is a bit strange. Please restructure like 
most bindings so the property names are before all the description.

> +  Some SOCs require additional clock for AXI bus.

Those SoCs should have a specific compatible string and you need to 
define which compatible strings have 2 clocks vs. 1 clock.

> +  The input clock for Xenon IP core should be named as "core".
> +  The optional AXI clock should be named as "axi".
> +  - clocks = <&core_clk>, <&axi_clock>;
> +  - clock-names = "core", "axi";
> +
> +- Register Set Size

Is this a property name?

> +  Different Xenon SDHC release has different register set size.
> +  The specific size should also refer to the SOC implementation.
> +
> +Optional Properties:
> +- Slot Index
> +  A single Xenon IP can support multiple slots.
> +  During initialization, each slot should set corresponding setting bit in
> +  some Xenon-specific registers. The corresponding bit is determined by
> +  this property.
> +  - xenon,slotno = <slot_index>;

Slots should probably be represented as child nodes with the reg 
property being the slot number.

Also, xenon is not a vendor prefix.

> +  If this property is not provided, Xenon IP should contain only one slot
> +  and the slot index will be 0x0 by default.
> +
> +- PHY Type

You're going to need to come of with a common binding for this.

> +  Xenon support mutilple types of PHYs.
> +  To select eMMC 5.1 PHY, set:
> +  - xenon,phy-type = "emmc 5.1 phy"
> +  eMMC 5.1 PHY is the default choice if this property is not provided.
> +  To select eMMC 5.0 PHY, set:
> +  - xenon,phy-type = "emmc 5.0 phy"
> +  To select SDH PHY, set:
> +  - xenon,phy-type = "sdh phy"
> +  Please note that eMMC PHY is a general PHY for eMMC/SD/SDIO, other than for
> +  eMMC only.
> +
> +- Customized eMMC PHY Parameters
> +  Some boards require different values of some specific eMMC PHY parameters.
> +  Some SOCs also require specific workaround to set eMMC PHY.
> +  These properties enable diverse boards to customize the eMMC PHY.
> +  The supported eMMC PHY parameters are listed in below. All those properties
> +  are only available for eMMC PHY 5.1 and eMMC PHY 5.0.
> +  ZNR
> +  valid range = [0:0x1F].
> +  ZNR is set as 0xF by default if this property is not provided.
> +  - xenon,phy-znr = <value>;
> +
> +  ZPR
> +  valid range = [0:0x1F].
> +  ZPR is set as 0xF by default if this property is not provided.
> +  - xenon,phy-zpr = <value>;

marvell is the vendor prefix.

> +
> +  Number of successful tuning times
> +  Set the number of required consecutive successful sampling points used to
> +  identify a valid sampling window, in tuning process.
> +  Valid range = [1:7]. Set as 0x4 by default if this property is not provided.
> +  - xenon,phy-nr-tun-times = <nr_times>;
> +
> +  Divider for TUN_STEP
> +  Set the divider for calculating TUN_STEP.
> +  Set as 64 by default if this property is not provided.
> +  - xenon,phy-tun-step-divider = <divider>;
> +
> +  Force PHY into slow mode.
> +  Only available when bus frequency lower than 50MHz in SDR mde.
> +  Disabled by default. Please do not enable it unless it is necessary.
> +  - xenon,phy-slow-mode;
> +
> +- Mask Conflict Error Report
> +  Disable Conflict Error alert on some SOC. Disabled by default.
> +  xenon,mask-conflict-err;
> +
> +- Re-tuning Counter
> +  Xenon SDHC SOC usually doesn't provide re-tuning counter in
> +  Capabilities Register 3 Bit[11:8].
> +  This property provides the re-tuning counter.
> +  xenon,tuning-count = <count>;
> +  If this property is not set, default re-tuning counter will
> +  be set as 0x9 in driver.
> +
> +- SOC PHY PAD Voltage Control register
> +  Some SOCs have SOC PHY PAD Voltage Control register outside Xenon IP.
> +  This register sets SOC PHY PAD Voltage to keep aligh with Vccq.
> +  Two properties provide information of this control register.
> +  These two properties are only valid when "marvell,armada-3700-sdhci"
> +  is selected. Both of them must be provided when "marvell,armada-3700-sdhci"
> +  is selected.
> +  - xenon,pad-type
> +    Two types: "sd" and "fixed-1-8v".
> +    If "sd" is slected, SOC PHY PAD is set as 3.3V at the beginning and is
> +    switched to 1.8V when SD in UHS-I.
> +    If "fixed-1-8v" is slected, SOC PHY PAD is fixed 1.8V, such as for eMMC.

You should be able to existing, common properties for i/o voltage 
capabilities/constraints.

> +  - reg
> +    Physical address and size of SOC PHY PAD register.
> +    Append after Xenon SDHC register space, as a second register field.
> +
> +  Please follow the examples with compatible "marvell,armada-3700-sdhci"
> +  in below.
> +
> +Example:
> +- For eMMC slot:
> +
> +	sdhci at aa0000 {
> +		compatible = "marvell,sdhci-xenon";
> +		reg = <0xaa0000 0x1000>;
> +		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>
> +		clocks = <&emmcclk>;
> +		clock-names = "core";
> +		xenon,slotno = <0>;
> +		xenon,phy-type = "emmc 5.1 phy";
> +		bus-width = <8>;
> +		tuning-count = <11>;
> +	};
> +
> +- For SD/SDIO slot:
> +
> +	sdhci at ab0000 {
> +		compatible = "marvell,sdhci-xenon";
> +		reg = <0xab0000 0x1000>;
> +		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>
> +		vqmmc-supply = <&sd_regulator>;
> +		clocks = <&sdclk>;
> +		clock-names = "core";
> +		bus-width = <4>;
> +		tuning-count = <9>;
> +	};
> +
> +- For eMMC slot with compatible "marvell,armada-3700-sdhci":
> +
> +	sdhci at aa0000 {
> +		compatible = "marvell,armada-3700-sdhci";
> +		reg = <0xaa0000 0x1000>,
> +		      <phy_addr 0x4>;
> +		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>
> +		clocks = <&emmcclk>;
> +		clock-names = "core";
> +		bus-width = <8>;
> +
> +		xenon,pad-type = "fixed-1-8v";
> +	};
> +
> +- For SD/SDIO slot with compatible "marvell,armada-3700-sdhci":
> +
> +	sdhci at ab0000 {
> +		compatible = "marvell,armada-3700-sdhci";
> +		reg = <0xab0000 0x1000>,
> +		      <phy_addr 0x4>;
> +		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>
> +		vqmmc-supply = <&sd_regulator>;
> +		clocks = <&sdclk>;
> +		clock-names = "core";
> +		bus-width = <4>;
> +
> +		xenon,pad-type = "sd";
> +	};
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 89adcd57aa25..4aa0eac9bfc7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -7582,6 +7582,7 @@ MARVELL XENON MMC/SD/SDIO HOST CONTROLLER DRIVER
>  M:	Ziji Hu <huziji@marvell.com>
>  L:	linux-mmc at vger.kernel.org
>  S:	Supported
> +F:	Documentation/devicetree/bindings/mmc/marvell,sdhci-xenon.txt
>  
>  MATROX FRAMEBUFFER DRIVER
>  L:	linux-fbdev at vger.kernel.org
> -- 
> git-series 0.8.10

^ permalink raw reply

* [PATCH/RFT 09/12] usb: host: ohci-da8xx: Add devicetree bindings documentation
From: Rob Herring @ 2016-10-10 21:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475858577-10366-10-git-send-email-ahaslam@baylibre.com>

On Fri, Oct 07, 2016 at 06:42:54PM +0200, ahaslam at baylibre.com wrote:
> From: Axel Haslam <ahaslam@baylibre.com>
> 
> This patch documents the device tree bindings required for
> the ohci controller found in TI da8xx family of SoC's
> 
> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
> ---
>  .../devicetree/bindings/usb/ohci-da8xx.txt         | 32 ++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/ohci-da8xx.txt
> 
> diff --git a/Documentation/devicetree/bindings/usb/ohci-da8xx.txt b/Documentation/devicetree/bindings/usb/ohci-da8xx.txt
> new file mode 100644
> index 0000000..e954ce5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/ohci-da8xx.txt
> @@ -0,0 +1,32 @@
> +DA8XX USB OHCI controller
> +
> +Required properties:
> +
> + - compatible: Should be "ti,da830-ohci"
> + - reg:        Should contain one register range i.e. start and length
> + - interrupts: Description of the interrupt line
> + - phys:       Phandle for the PHY device
> + - phy-names:  Should be "usb-phy"
> +
> +Optional properties:
> + - vbus-gpio:  If present, specifies a gpio that needs to be

vbus-gpios

> +               activated for the bus to be powered.
> + - oci-gpio:   If present, specifies a gpio that needs to be

oci-gpios

> +               activated for the overcurrent detection.
> + - power_on_delay: Power On to Power Good time - in ms.

power-on-delay-ms

> +
> +Example for omap138-lck:
> +
> +usb_phy: usb-phy {
> +        compatible = "ti,da830-usb-phy";
> +        #phy-cells = <1>;
> +        status = "disabled";
> +};
> +usb11: usb11 at 0225000 {
> +        compatible = "ti,da830-ohci";
> +        reg = <0x225000 0x1000>;
> +        interrupts = <59>;
> +        phys = <&usb_phy 1>;
> +        phy-names = "usb-phy";
> +        status = "disabled";
> +};
> -- 
> 2.7.1
> 

^ permalink raw reply

* [PATCH v2] arm64: dts: rename ns2.txt to brcm,ns2.txt
From: Rob Herring @ 2016-10-10 21:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475959684-18085-1-git-send-email-scott.branden@broadcom.com>

On Sat, Oct 08, 2016 at 01:48:04PM -0700, Scott Branden wrote:
> Rename ns2.txt to brcm,ns2.txt to match naming convention followed
> by rest of Broadcom binding documentation.
> 
> Signed-off-by: Scott Branden <scott.branden@broadcom.com>
> ---
>  Documentation/devicetree/bindings/arm/bcm/{ns2.txt => brcm,ns2.txt} | 0
>  1 file changed, 0 insertions(+), 0 deletions(-)
>  rename Documentation/devicetree/bindings/arm/bcm/{ns2.txt => brcm,ns2.txt} (100%)

Acked-by: Rob Herring <robh@kernel.org>

> 
> diff --git a/Documentation/devicetree/bindings/arm/bcm/ns2.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,ns2.txt
> similarity index 100%
> rename from Documentation/devicetree/bindings/arm/bcm/ns2.txt
> rename to Documentation/devicetree/bindings/arm/bcm/brcm,ns2.txt
> -- 
> 2.5.0
> 

^ permalink raw reply

* [PATCH v2 1/2] dt-bindings: add bindings doc for ZTE VOU display controller
From: Rob Herring @ 2016-10-10 21:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161009074910.GA15400@tiger>

On Sun, Oct 09, 2016 at 03:49:10PM +0800, Shawn Guo wrote:
> On Mon, Oct 03, 2016 at 12:44:29PM -0500, Rob Herring wrote:
> > > +Example:
> > > +
> > > +vou: vou at 1440000 {
> > > +	compatible = "zte,zx296718-vou";
> > > +	#address-cells = <1>;
> > > +	#size-cells = <1>;
> > > +	reg = <0x1440000 0x10000>;
> > > +	ranges;
> > 
> > You still have overlapping addresses. Explicitly list the sub ranges in 
> > reg here used by the VOU driver if the driver usage doesn't overlap. If 
> > there is overlap (2 drivers accessing the same range), then you need 
> > some APIs between the components (or possibly regmap).
> 
> The driver matching "zte,zx296718-vou" doesn't map or access the any
> 'reg' address.  The 'reg' property here is more like a hint telling
> that the VOU block covers the address space of all child devices.
> 
> I will simply drop the 'reg' property here.
> 
> > Also, don't do an empty ranges here. Fill it in so the child nodes are 
> > just offsets of 0x1440000
> 
> Okay.  I thought that empty 'ranges' is fine as long as parent and child
> address spaces are identical (1:1 mapping).

It is fine, but it's just better policy to limit the scope of things.

> So with your suggestion, I made the changes below.  Let me know if this
> is still not what you are asking for.

Looks fine. With that,

Acked-by: Rob Herring <robh@kernel.org>

> 
> Shawn
> 
> -----8<-----------------
> 
> diff --git a/Documentation/devicetree/bindings/display/zte,vou.txt b/Documentation/devicetree/bindings/display/zte,vou.txt
> index d03ba4c4810c..6bb4ab2517ef 100644
> --- a/Documentation/devicetree/bindings/display/zte,vou.txt
> +++ b/Documentation/devicetree/bindings/display/zte,vou.txt
> @@ -56,14 +56,13 @@ vou: vou at 1440000 {
>         compatible = "zte,zx296718-vou";
>         #address-cells = <1>;
>         #size-cells = <1>;
> -       reg = <0x1440000 0x10000>;
> -       ranges;
> +       ranges = <0 0x1440000 0x10000>;
>  
> -       dpc: dpc at 1440000 {
> +       dpc: dpc at 0 {
>                 compatible = "zte,zx296718-dpc";
> -               reg = <0x1440000 0x1000>, <0x1441000 0x1000>,
> -                     <0x1445000 0x1000>, <0x1446000 0x1000>,
> -                     <0x144a000 0x1000>;
> +               reg = <0x0000 0x1000>, <0x1000 0x1000>,
> +                     <0x5000 0x1000>, <0x6000 0x1000>,
> +                     <0xa000 0x1000>;
>                 reg-names = "osd", "timing_ctrl",
>                             "dtrc", "vou_ctrl",
>                             "otfppu";
> @@ -74,9 +73,9 @@ vou: vou at 1440000 {
>                               "main_wclk", "aux_wclk";
>         };
>  
> -       hdmi: hdmi at 144c000 {
> +       hdmi: hdmi at c000 {
>                 compatible = "zte,zx296718-hdmi";
> -               reg = <0x144c000 0x4000>;
> +               reg = <0xc000 0x4000>;
>                 interrupts = <GIC_SPI 82 IRQ_TYPE_EDGE_RISING>;
> 

^ permalink raw reply

* [PATCH v2 5/8] dt/bindings: Update binding for PM domain idle states
From: Lina Iyer @ 2016-10-10 22:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <ffc0b521-329a-d41f-c952-bb9c4877ea87@arm.com>

On Mon, Oct 10 2016 at 11:13 -0600, Sudeep Holla wrote:
>
>
>On 10/10/16 17:43, Lina Iyer wrote:
>>On Mon, Oct 10 2016 at 09:45 -0600, Sudeep Holla wrote:
>>>
>>>
>>>On 07/10/16 23:36, Lina Iyer wrote:
>>>>Update DT bindings to describe idle states of PM domains.
>>>>
>>>>This patch is based on the original patch by Marc Titinger.
>>>>
>>>>Cc: <devicetree@vger.kernel.org>
>>>>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>
>>>>Acked-by: Rob Herring <robh@kernel.org>
>>>>---
>>>>.../devicetree/bindings/power/power_domain.txt     | 38
>>>>++++++++++++++++++++++
>>>>1 file changed, 38 insertions(+)
>>>>
>>>>diff --git a/Documentation/devicetree/bindings/power/power_domain.txt
>>>>b/Documentation/devicetree/bindings/power/power_domain.txt
>>>>index 025b5e7..7f8f27e 100644
>>>>--- a/Documentation/devicetree/bindings/power/power_domain.txt
>>>>+++ b/Documentation/devicetree/bindings/power/power_domain.txt
>>>>@@ -29,6 +29,10 @@ Optional properties:
>>>>   specified by this binding. More details about power domain
>>>>specifier are
>>>>   available in the next section.
>>>>
>>>>+- domain-idle-states : A phandle of an idle-state that shall be
>>>>soaked into a
>>>>+                generic domain power state. The idle state
>>>>definitions are
>>>>+                compatible with arm,idle-state specified in [1].
>>>>+
>>>
>>>Please do add the following details to the binding. IMO, this binding is
>>>not complete in terms of specification as there are few open questions:
>>>
>>>1. What not define a standard compatible instead of "arm,idle-state" ?
>>>  I agree it can be used, but as part of this *generic* binding, IMO
>>>  it's better to have something generic and can be used by devices.
>>>  Otherwise, this binding becomes CPU specific, that too ARM CPU
>>>  specific.
>>>
>>We had gone down this path of having a separate DT bindings for domains
>>that is not arm,idle-state. See RFC patches. But the binding did closely
>>match this and it so was suggested that we use arm,idle-state which is
>>already defined.
>>
>
>Either we say this binding is ARM CPU specific or generic, I can't
>understand this mix 'n' match really. You have removed all the CPUIdle
>stuff from this series which is good and makes it simpler, but linking
>it to only "arm,idle-state" make be feel it's not generic. OK I will
>have a look at the RFC as why generic compatible was rejected.
>
I will look for the discussion around it as well. A initial look through
didn't get me the thread I was looking for.

>>>2. Now taking CPU as a special device, how does this co-exist with the
>>>  cpu-idle-states ? Better to have some description may be in the ARM
>>>  CPU idle binding document(not here of-course)
>>>
>>The is a binding for a generic PM domain. This has no bearing on the CPU
>>or its idle states. Its just that the data is compatible with
>>arm,idle-state.
>>
>
>I understand that but it's not that simple which I assume you *do*
>agree. Hence may need bit of an explanation in the binding(not here
>of-course as I mentioned earlier, but in the CPU Idle bindings).
>Please consider DT bindings as any other specification. All I am
>asking is more description in the binding.
>
Any ideas of what description you would like to see? It seemed fairly
explanatory in the idle-states.txt, so I didn't go into depth here.

>>>3. I still haven't seen any explanation for not considering complete
>>>  hierarchical power domain representation which was raised in earlier
>>>  versions. I had provided example for the proposal. I just saw them
>>>  already in use in the upstream kernel by Renasas. e.g.:
>>>  arch/arm/boot/dts/r8a73a4.dtsi
>>>
>>Hierarchical power domains have been available for few years in DT. The
>>OF features of domains have always supported it. Platforms are free to
>>define domains in hierarchy they seem fit for their SoCs. This is a
>>feature that is available today and is not being modified in these
>>patches. It will be creating confusion if I talk about hierarchical
>>domains which are obvious and irrelevant to this series.
>>
>
>Agreed and sorry if I created any confusion. But this binding doesn't
>clearly state how to build up the hierarchy if the leaf node is not a
>power-domain node and I am just trying have those clarifications in the
>binding. It would be good if those details are *explicitly* mentioned in
>the binding, not this particularly, but in CPU Idle one when you
>introduce the user of that.
>
As we have today, devices have their own way of figuring out their idle
states, they are not represented in DT (CPU being an exception). 

>>>  How does that fit with your proposal, though you have not made one
>>>  yet for CPUs in this binding ? In the above file, CPUs have either
>>>  own power domain inside the L2 one which is cluster level power
>>>  domain.
>>>
>>Again, this series is not about the CPUs. This is about adding features
>>to genpd that may be used in other contexts including cpuidle in the
>>future.
>>
>
>Yes I understand and hence I was confused as why I don't see an
>*generic* compatible but just *arm,idle-states* in the example.
>
>>>One must be able to get answers to these above questions with this
>>>binding. Until then it's *incomplete* though it may be correct.
>>>
>>I have always tried to answer all your questions. If anything remains
>>unclarified pls. bring it up.
>>
>
>It's not about questions, and definitely you have answered all my
>questions, no argument there at all. Now we need to make those useful
>discussions part of this binding so that it's *self explanatory* and
>one need not refer back these discussions when writing DT for some
>different SoC which differs from this. Again that could be part of
>your CPUIdle series, I just raised it here as it got mixed sense from
>this series. It was hard to be not to associate CPUIdle for reasons
>mentioned above.
>

Thanks,
Lina

^ permalink raw reply

* [PATCH v3 10/12] scsi/ncr5380: Expedite register polling
From: Finn Thain @ 2016-10-10 22:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161010091709.GY1041@n2100.armlinux.org.uk>


On Mon, 10 Oct 2016, Russell King - ARM Linux wrote:

> On Mon, Oct 10, 2016 at 12:46:53AM -0400, Finn Thain wrote:
> > Avoid the call to NCR5380_poll_politely2() when possible. The call is 
> > easily short-circuited on the PIO fast path, using the inline wrapper. 
> > This requires that the NCR5380_read macro be made available before any 
> > #include "NCR5380.h" so a few declarations have to be moved too.
> > 
> > Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> > Reviewed-by: Hannes Reinecke <hare@suse.com>
> > Tested-by: Ondrej Zary <linux@rainbow-software.org>
> > Tested-by: Michael Schmitz <schmitzmic@gmail.com>
> > ---
> 
> > diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
> > index ae1d4c6..fb7600d 100644
> > --- a/drivers/scsi/arm/cumana_1.c
> > +++ b/drivers/scsi/arm/cumana_1.c
> > @@ -29,6 +29,10 @@
> >  #define NCR5380_implementation_fields	\
> >  	unsigned ctrl
> >  
> > +struct NCR5380_hostdata;
> > +static u8 cumanascsi_read(struct NCR5380_hostdata *, unsigned int);
> > +static void cumanascsi_write(struct NCR5380_hostdata *, unsigned int, u8);
> > +
> >  #include "../NCR5380.h"
> >  
> >  #define CTRL	0x16fc
> 
> This seems to be non-obviously unrelated to this commit - should it be 
> in some other commit?
> 

The source of the problem here is the #include "../NCR5380.h", because 
that header file both declares struct NCR5380_hostdata and (with this 
patch) it also calls cumanascsi_read(). That means cumanascsi_read() has 
to be declared earlier, and that in turn requires an incomplete definition 
of struct NCR5380_hostdata. The commit log alludes to the problem but 
could be made more explicit if you would like (?).

BTW, this problem doesn't arise in the other six 5380 drivers because each 
one implements NCR5380_read() as a macro. It would be nice to get rid of 
the macros in favour of an ops struct (in the course of converting the 
driver to a library module) but I doubt that this is feasible now that 
I've seen the performance benefit of this patch series.

In the absence of link time optimization, the library module design would 
prevent the inlining of functions like cumanascsi_read(). Since every byte 
transfered by the 5380 in a PIO transfer requires at least 5 chip register 
accesses, function calls would be prohibitively expensive. So I think we 
are stuck with inline accessors or macros.

-- 

^ permalink raw reply

* [PATCH/RFT 07/12] USB: ohci-da8xx: Request gpios and handle interrupt in the driver
From: David Lechner @ 2016-10-10 23:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475858577-10366-8-git-send-email-ahaslam@baylibre.com>

On 10/07/2016 11:42 AM, ahaslam at baylibre.com wrote:
> From: Axel Haslam <ahaslam@baylibre.com>
>
> Currently requesting the vbus and overcurrent gpio is handled on
> the board specific file. But this does not play well moving to
> device tree.
>
> In preparation to migrate to a device tree boot, handle requesting
> gpios and overcurrent interrupt on the usb driver itself, thus avoiding
> callbacks to arch/mach*
>

Instead of using gpios, it seems like it would be better to use a 
regulator here. I don't know of any real-life cases, but who is to say 
someone will not design a board that uses a regulator controlled by I2C 
instead of gpios or something like that.

Then, boards that don't have gpios can just use a fixed regulator (or 
you can make the regulator optional). Using a regulator would also allow 
users to decide how to respond to overcurrent events (by supplying their 
own regulator driver) instead of the behavior being dictated by the ohci 
driver.

In my particular area of interest (LEGO MINDSTORMS EV3), the 5V 
(hardware) regulator for VBUS does use gpios, but the 5V is also shared 
with the LEGO input and output ports. So what I would ultimately like to 
be able to do is have userspace notified of an overcurrent event and let 
userspace decided when to turn the vbus back on. For example, someone 
might plug something into one of the LEGO input or output ports that 
causes a short circuit. I would like to display a notification to the 
user and wait for them to correct the problem and then press a button to 
turn the power back on.

This will require some modifications to the regulator subsystem though. 
I actually started work on this a while back, but haven't had the time 
to pursue it any farther.

Here are my WIP patches in case there is any interest:
* 
https://github.com/dlech/ev3dev-kernel/commit/541a42b3b8ed639e95bbc835df3292f80190c789
* 
https://github.com/dlech/ev3dev-kernel/commit/2ba99b1ad6a06c944dd33a073f54044e71b75ae6
* 
https://github.com/dlech/ev3dev-kernel/commit/cdb03caa50e64931d4f2836c648739aa4385ed3b
* 
https://github.com/dlech/ev3dev-kernel/commit/9d6b50cde34b51309c74d97c26b1430c7ff6aa0f

^ permalink raw reply

* [PATCH 0/8] pinctrl: aspeed: Fixes for core and g5, implement remaining pins
From: Andrew Jeffery @ 2016-10-10 23:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdZWbx1_SYJMOn40teQaEw1JAq80kDAp7N+OYaMRRO6NBg@mail.gmail.com>

On Mon, 2016-10-10 at 09:59 +0200, Linus Walleij wrote:
> On Tue, Sep 27, 2016 at 4:50 PM, Andrew Jeffery <andrew@aj.id.au> wrote:
> 
> > 
> > The initial Aspeed pinctrl patches implemented a subset of pins for each of the
> > g4 and g5 SoCs. This series provides a number of fixes to the initial patches,
> > mostly for issues identified in the g5 driver. The fixes account for the first
> > half of the series (up to and including "pinctrl: aspeed-g5: Fix pin
> > association of SPI1 function") and should be applied for 4.9.
> Those are applied for fixes.

Thanks!

> 
> > 
> > The second half, from "pinctrl: aspeed: Enable capture of off-SCU pinmux
> > state", implements some additional functionality in the core engine for the
> > Aspeed SoCs and follows up with patches implementing mux configuration tables
> > for all remaining pins. Given the significant additions in the last few
> > patches, their lateness in the cycle and the light testing they have received
> > they are best left for 4.10, but I'm keen to get them out for review.
> I'm holding these back until v4.9-rc1 is out.

No worries; they need some discussion when you have the time.

Cheers,

Andrew
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161011/339a02a0/attachment.sig>

^ permalink raw reply

* [PATCH/RFT 08/12] ARM: davinci: register the usb20_phy clock on the SoC file
From: David Lechner @ 2016-10-10 23:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475858577-10366-9-git-send-email-ahaslam@baylibre.com>

On 10/07/2016 11:42 AM, ahaslam at baylibre.com wrote:
> From: Axel Haslam <ahaslam@baylibre.com>
>
> The usb20_phy clock needs to be registered for the driver to be able
> to get and enable a clock. Currently the usb phy clocks are registered
> form board files, which will not be called during a device tree based
> boot.
>
> To be able to probe correctly usb form a device tree boot, register
> the usb phy clocks form the SoC specific init.
>
> Unfourtunatly, davinci does not have proper clock support on device tree
> yet, so by registering the clock form de SoC specific file we are
> forced to hardcode the parent clock, and cannot select refclkin as
> parent for any of the phy clocks of the da850 family.

FYI, I have started working on the clocks as well if you want to take it 
and run with it.

https://github.com/dlech/ev3dev-kernel/compare/9d6b50cde34b51309c74d97c26b1430c7ff6aa0f...d02084598785c369fdb23884171cbbec4fef77b0

(Ignore the ev3dev commit stuck in the middle there.)

>
> As none of the current da850 based boards currently in mainline use
> refclkin as source. I guess we can live with this limitation until clocks
> are correctly represented through CCF/device tree.
>

^ permalink raw reply

* [PATCH/RFT 09/12] usb: host: ohci-da8xx: Add devicetree bindings documentation
From: David Lechner @ 2016-10-10 23:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475858577-10366-10-git-send-email-ahaslam@baylibre.com>

On 10/07/2016 11:42 AM, ahaslam at baylibre.com wrote:
> From: Axel Haslam <ahaslam@baylibre.com>
>
> This patch documents the device tree bindings required for
> the ohci controller found in TI da8xx family of SoC's
>
> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
> ---
>  .../devicetree/bindings/usb/ohci-da8xx.txt         | 32 ++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/ohci-da8xx.txt
>
> diff --git a/Documentation/devicetree/bindings/usb/ohci-da8xx.txt b/Documentation/devicetree/bindings/usb/ohci-da8xx.txt
> new file mode 100644
> index 0000000..e954ce5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/ohci-da8xx.txt
> @@ -0,0 +1,32 @@
> +DA8XX USB OHCI controller
> +
> +Required properties:
> +
> + - compatible: Should be "ti,da830-ohci"
> + - reg:        Should contain one register range i.e. start and length
> + - interrupts: Description of the interrupt line
> + - phys:       Phandle for the PHY device
> + - phy-names:  Should be "usb-phy"
> +

If these are required, shouldn't they say "Must" instead of "Should"?

> +Optional properties:
> + - vbus-gpio:  If present, specifies a gpio that needs to be
> +               activated for the bus to be powered.
> + - oci-gpio:   If present, specifies a gpio that needs to be
> +               activated for the overcurrent detection.
> + - power_on_delay: Power On to Power Good time - in ms.
> +
> +Example for omap138-lck:
> +
> +usb_phy: usb-phy {
> +        compatible = "ti,da830-usb-phy";
> +        #phy-cells = <1>;
> +        status = "disabled";
> +};
> +usb11: usb11 at 0225000 {
> +        compatible = "ti,da830-ohci";
> +        reg = <0x225000 0x1000>;
> +        interrupts = <59>;
> +        phys = <&usb_phy 1>;
> +        phy-names = "usb-phy";
> +        status = "disabled";
> +};
>

^ permalink raw reply

* [PATCH 1/5] dt-bindings: add vendor prefix for ILI Technology Corp
From: Icenowy Zheng @ 2016-10-11  0:33 UTC (permalink / raw)
  To: linux-arm-kernel

ILI Technology Corp (a.k.a Ilitek, http://www.ilitek.com/index-e.asp ) is a
company that produces LCD driver ICs and touch screen controller ICs.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 24c6f65..4d37fdc 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -130,6 +130,7 @@ i2se	I2SE GmbH
 ibm	International Business Machines (IBM)
 idt	Integrated Device Technologies, Inc.
 ifi	Ingenieurburo Fur Ic-Technologie (I/F/I)
+ilitek	ILI Technologies Corp.
 img	Imagination Technologies Ltd.
 infineon Infineon Technologies
 inforce	Inforce Computing
-- 
2.10.1

^ permalink raw reply related

* [PATCH 2/5] dt-bindings: add binding for Ilitek ili2139 touchscreen IC
From: Icenowy Zheng @ 2016-10-11  0:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161011003359.26079-1-icenowy@aosc.xyz>

Ilitek ili2139 is a touchscreen IC used in several tablet products, for
example, Colorfly E708 Q1.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 .../bindings/input/touchscreen/ilitek_ili2139.txt     | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ilitek_ili2139.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/ilitek_ili2139.txt b/Documentation/devicetree/bindings/input/touchscreen/ilitek_ili2139.txt
new file mode 100644
index 0000000..72d2352
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/ilitek_ili2139.txt
@@ -0,0 +1,19 @@
+* Ilitek ili2139 touchscreen controller
+
+Required properties:
+- compatible		  : "ilitek,ili2139"
+- reg			  : I2C slave address of the chip (0x41)
+- interrupt-parent	  : a phandle pointing to the interrupt controller
+			    serving the interrupt for this chip
+- interrupts		  : interrupt specification for the ili2139 interrupt
+
+Example:
+
+i2c at 00000000 {
+	ili2139: touchscreen at 41 {
+		compatible = "ilitek,ili2139"
+		reg = <0x41>;
+		interrupt-parent = <&pio>;
+		interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>;
+	};
+};
-- 
2.10.1

^ permalink raw reply related

* [PATCH 3/5] Input: add driver for Ilitek ili2139 touch IC
From: Icenowy Zheng @ 2016-10-11  0:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161011003359.26079-1-icenowy@aosc.xyz>

This driver adds support for Ilitek ili2139 touch IC, which is used in
several Colorfly tablets (for example, Colorfly E708 Q1, which is an
Allwinner A31s tablet with mainline kernel support).

Theortically it may support more Ilitek touch ICs, however, only ili2139
is used in any mainlined device.

It supports device tree enumeration, with screen resolution and axis
quirks configurable.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 drivers/input/touchscreen/Kconfig   |  14 ++
 drivers/input/touchscreen/Makefile  |   1 +
 drivers/input/touchscreen/ili2139.c | 320 ++++++++++++++++++++++++++++++++++++
 3 files changed, 335 insertions(+)
 create mode 100644 drivers/input/touchscreen/ili2139.c

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 5079813..bb4d9d2 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -348,6 +348,20 @@ config TOUCHSCREEN_ILI210X
 	  To compile this driver as a module, choose M here: the
 	  module will be called ili210x.
 
+config TOUCHSCREEN_ILI2139
+	tristate "Ilitek ILI2139 based touchscreen"
+	depends on I2C
+	depends on OF
+	help
+	  Say Y here if you have a ILI2139 based touchscreen
+	  controller. Such kind of chipsets can be found in several
+	  Colorfly tablets.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here; the
+	  module will be called ili2139.
+
 config TOUCHSCREEN_IPROC
 	tristate "IPROC touch panel driver support"
 	depends on ARCH_BCM_IPROC || COMPILE_TEST
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 81b8645..930b5e2 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL)	+= egalax_ts_serial.o
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
+obj-$(CONFIG_TOUCHSCREEN_ILI2139)	+= ili2139.o
 obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC)	+= imx6ul_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
diff --git a/drivers/input/touchscreen/ili2139.c b/drivers/input/touchscreen/ili2139.c
new file mode 100644
index 0000000..65c2dea
--- /dev/null
+++ b/drivers/input/touchscreen/ili2139.c
@@ -0,0 +1,320 @@
+/* -------------------------------------------------------------------------
+ * Copyright (C) 2016, Icenowy Zheng <icenowy@aosc.xyz>
+ *
+ * Derived from:
+ *  ili210x.c
+ *  Copyright (C) Olivier Sobrie <olivier@sobrie.be>
+ *
+ *  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.
+ *
+ *  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/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+
+#define DEFAULT_POLL_PERIOD	20
+
+#define MAX_TOUCHES		10
+#define COMPATIBLE_TOUCHES	2
+
+/* Touchscreen commands */
+#define REG_TOUCHDATA		0x10
+#define REG_TOUCHSUBDATA	0x11
+#define REG_PANEL_INFO		0x20
+#define REG_FIRMWARE_VERSION	0x40
+#define REG_PROTO_VERSION	0x42
+
+#define SUBDATA_STATUS_TOUCH_POINT	0x80
+#define SUBDATA_STATUS_RELEASE_POINT	0x00
+
+struct finger {
+	u8 x_low;
+	u8 x_high;
+	u8 y_low;
+	u8 y_high;
+} __packed;
+
+struct touchdata {
+	u8 length;
+	struct finger finger[COMPATIBLE_TOUCHES];
+} __packed;
+
+struct touch_subdata {
+	u8 status;
+	struct finger finger;
+} __packed;
+
+struct panel_info {
+	struct finger finger_max;
+	u8 xchannel_num;
+	u8 ychannel_num;
+} __packed;
+
+struct firmware_version {
+	u8 id;
+	u8 major;
+	u8 minor;
+} __packed;
+
+struct ili2139 {
+	struct i2c_client *client;
+	struct input_dev *input;
+	unsigned int poll_period;
+	struct delayed_work dwork;
+	struct touchscreen_properties prop;
+	int slots[MAX_TOUCHES];
+	int ids[MAX_TOUCHES];
+	struct input_mt_pos pos[MAX_TOUCHES];
+};
+
+static int ili2139_read_reg(struct i2c_client *client, u8 reg, void *buf,
+			    size_t len)
+{
+	struct i2c_msg msg[2] = {
+		{
+			.addr	= client->addr,
+			.flags	= 0,
+			.len	= 1,
+			.buf	= &reg,
+		},
+		{
+			.addr	= client->addr,
+			.flags	= I2C_M_RD,
+			.len	= len,
+			.buf	= buf,
+		}
+	};
+
+	if (i2c_transfer(client->adapter, msg, 2) != 2) {
+		dev_err(&client->dev, "i2c transfer failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void ili2139_work(struct work_struct *work)
+{
+	int id;
+	struct ili2139 *priv = container_of(work, struct ili2139,
+					    dwork.work);
+	struct i2c_client *client = priv->client;
+	struct touchdata touchdata;
+	struct touch_subdata subdata;
+	int error;
+
+	error = ili2139_read_reg(client, REG_TOUCHDATA,
+				 &touchdata, sizeof(touchdata));
+	if (error) {
+		dev_err(&client->dev,
+			"Unable to get touchdata, err = %d\n", error);
+		return;
+	}
+
+	for (id = 0; id < touchdata.length; id++) {
+		error = ili2139_read_reg(client, REG_TOUCHSUBDATA, &subdata,
+					 sizeof(subdata));
+		if (error) {
+			dev_err(&client->dev,
+				"Unable to get touch subdata, err = %d\n",
+				error);
+			return;
+		}
+
+		priv->ids[id] = subdata.status & 0x3F;
+
+		/* The sequence changed in the v2 subdata protocol. */
+		touchscreen_set_mt_pos(&priv->pos[id], &priv->prop,
+			(subdata.finger.x_high | (subdata.finger.x_low << 8)),
+			(subdata.finger.y_high | (subdata.finger.y_low << 8)));
+	}
+
+	input_mt_assign_slots(priv->input, priv->slots, priv->pos,
+			      touchdata.length, 0);
+
+	for (id = 0; id < touchdata.length; id++) {
+		input_mt_slot(priv->input, priv->slots[id]);
+		input_mt_report_slot_state(priv->input, MT_TOOL_FINGER,
+					   subdata.status &
+					   SUBDATA_STATUS_TOUCH_POINT);
+		input_report_abs(priv->input, ABS_MT_POSITION_X,
+				 priv->pos[id].x);
+		input_report_abs(priv->input, ABS_MT_POSITION_Y,
+				 priv->pos[id].y);
+	}
+
+	input_mt_sync_frame(priv->input);
+	input_sync(priv->input);
+
+	schedule_delayed_work(&priv->dwork,
+			      msecs_to_jiffies(priv->poll_period));
+}
+
+static irqreturn_t ili2139_irq(int irq, void *irq_data)
+{
+	struct ili2139 *priv = irq_data;
+
+	schedule_delayed_work(&priv->dwork, 0);
+
+	return IRQ_HANDLED;
+}
+
+static int ili2139_i2c_probe(struct i2c_client *client,
+				       const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct ili2139 *priv;
+	struct input_dev *input;
+	struct panel_info panel;
+	struct firmware_version firmware;
+	int xmax, ymax;
+	int error;
+
+	dev_dbg(dev, "Probing for ILI2139 I2C Touschreen driver");
+
+	if (client->irq <= 0) {
+		dev_err(dev, "No IRQ!\n");
+		return -ENODEV;
+	}
+
+	/* Get firmware version */
+	error = ili2139_read_reg(client, REG_FIRMWARE_VERSION,
+				 &firmware, sizeof(firmware));
+	if (error) {
+		dev_err(dev, "Failed to get firmware version, err: %d\n",
+			error);
+		return error;
+	}
+
+	/* get panel info */
+	error = ili2139_read_reg(client, REG_PANEL_INFO, &panel, sizeof(panel));
+	if (error) {
+		dev_err(dev, "Failed to get panel information, err: %d\n",
+			error);
+		return error;
+	}
+
+	xmax = panel.finger_max.x_low | (panel.finger_max.x_high << 8);
+	ymax = panel.finger_max.y_low | (panel.finger_max.y_high << 8);
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	input = devm_input_allocate_device(dev);
+	if (!priv || !input)
+		return -ENOMEM;
+
+	priv->client = client;
+	priv->input = input;
+	priv->poll_period = DEFAULT_POLL_PERIOD;
+	INIT_DELAYED_WORK(&priv->dwork, ili2139_work);
+
+	/* Setup input device */
+	input->name = "ILI2139 Touchscreen";
+	input->id.bustype = BUS_I2C;
+	input->dev.parent = dev;
+
+	__set_bit(EV_SYN, input->evbit);
+	__set_bit(EV_KEY, input->evbit);
+	__set_bit(EV_ABS, input->evbit);
+
+	/* Multi touch */
+	input_mt_init_slots(input, MAX_TOUCHES, INPUT_MT_DIRECT |
+			    INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);
+	input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0);
+	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0);
+
+	touchscreen_parse_properties(input, true, &priv->prop);
+
+	input_set_drvdata(input, priv);
+	i2c_set_clientdata(client, priv);
+
+	error = devm_request_irq(dev, client->irq, ili2139_irq,
+				 IRQF_TRIGGER_FALLING, client->name, priv);
+	if (error) {
+		dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n",
+			error);
+		return error;
+	}
+
+	error = input_register_device(priv->input);
+	if (error) {
+		dev_err(dev, "Cannot register input device, err: %d\n", error);
+		return error;
+	}
+
+	device_init_wakeup(&client->dev, 1);
+
+	dev_dbg(dev,
+		"ILI2139 initialized (IRQ: %d), firmware version %d.%d.%d",
+		client->irq, firmware.id, firmware.major, firmware.minor);
+
+	return 0;
+}
+
+static int ili2139_i2c_remove(struct i2c_client *client)
+{
+	struct ili2139 *priv = i2c_get_clientdata(client);
+
+	cancel_delayed_work_sync(&priv->dwork);
+
+	return 0;
+}
+
+static int __maybe_unused ili2139_i2c_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	if (device_may_wakeup(&client->dev))
+		enable_irq_wake(client->irq);
+
+	return 0;
+}
+
+static int __maybe_unused ili2139_i2c_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	if (device_may_wakeup(&client->dev))
+		disable_irq_wake(client->irq);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ili2139_i2c_pm,
+			 ili2139_i2c_suspend, ili2139_i2c_resume);
+
+static const struct i2c_device_id ili2139_i2c_id[] = {
+	{ "ili2139", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ili2139_i2c_id);
+
+static struct i2c_driver ili2139_ts_driver = {
+	.driver = {
+		.name = "ili2139_i2c",
+		.pm = &ili2139_i2c_pm,
+	},
+	.id_table = ili2139_i2c_id,
+	.probe = ili2139_i2c_probe,
+	.remove = ili2139_i2c_remove,
+};
+
+module_i2c_driver(ili2139_ts_driver);
+
+MODULE_AUTHOR("Olivier Sobrie <olivier@sobrie.be>");
+MODULE_DESCRIPTION("ILI2139 I2C Touchscreen Driver");
+MODULE_LICENSE("GPL");
-- 
2.10.1

^ permalink raw reply related

* [PATCH 4/5] MAINTAINERS: Add myself as maintainer of ili2139 touchscreen driver
From: Icenowy Zheng @ 2016-10-11  0:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161011003359.26079-1-icenowy@aosc.xyz>

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a009e00..8f8341b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6112,6 +6112,12 @@ M:	Stanislaw Gruszka <stf_xl@wp.pl>
 S:	Maintained
 F:	drivers/usb/atm/ueagle-atm.c
 
+ILI2139 TOUCHSCREEN DRIVER
+M:	Icenowy Zheng <icenowy@aosc.xyz>
+S:	Maintained
+F:	Documentation/devicetree/bindings/input/touchscreen/ilitek_ili2139.txt
+F:	drivers/input/touchscreen/ili2139.c
+
 INA209 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
 L:	linux-hwmon at vger.kernel.org
-- 
2.10.1

^ permalink raw reply related

* [PATCH 5/5] ARM: dts: sun6i: enable ili2139 on Colorfly E708 Q1
From: Icenowy Zheng @ 2016-10-11  0:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161011003359.26079-1-icenowy@aosc.xyz>

Many users report that their Colorfly E708 Q1's come with ili2139 touch
IC. This patch adds the device node of this IC.

It seems that two devices are attached to I2C bus 1: a ili2139 touch
controller at 0x41, and a stil unknown device at 0x38. So make PA2
controlled by a dummy regulator node, rather than a power sequence GPIO
for ili2139.

There's also some users who report that their tablets come with touch
screen with Goodix GT911 touch IC. In the device, the touch IC is
connected on the screen rather soldered on the PCB, so the two touch
screens may be both acceptable FRUs of the tablet. They have different
addresses, and may be runtime detectable. (The Allwinner BSP kernel have
such a detection method, however, mainline kernel have no such method
now except enable both touch ICs' driver and wait for one driver's
failure)

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 arch/arm/boot/dts/sun6i-a31s-colorfly-e708-q1.dts | 48 +++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31s-colorfly-e708-q1.dts b/arch/arm/boot/dts/sun6i-a31s-colorfly-e708-q1.dts
index 882a4d8..73ac574 100644
--- a/arch/arm/boot/dts/sun6i-a31s-colorfly-e708-q1.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-colorfly-e708-q1.dts
@@ -47,6 +47,38 @@
 / {
 	model = "Colorfly E708 Q1 tablet";
 	compatible = "colorfly,e708-q1", "allwinner,sun6i-a31s";
+
+	/* This is actually a common reset line for both the
+	 * touchscreen and the accelerometer.
+	 */
+	i2c1_on: i2c1_on {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c1_on_e708_q1>;
+
+		regulator-name = "i2c1_on";
+		regulator-min-microvolt = "3000000";
+		regulator-max-microvolt = "3000000";
+		regulator-always-on;
+		gpio = <&pio 0 2 GPIO_ACTIVE_HIGH>; /* PA2 */
+		enable-active-high;
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+
+	ctp at 41 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&ili2139_int_e708_q1>;
+
+		compatible = "ilitek,ili2139", "ili2139";
+		reg = <0x41>;
+		interrupt-parent = <&pio>;
+		interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>; /* PA3 */
+	};
 };
 
 &lradc {
@@ -61,6 +93,22 @@
 	};
 };
 
+&pio {
+	i2c1_on_e708_q1: i2c1_on at 0 {
+		allwinner,pins = "PA2";
+	        allwinner,function = "gpio_out";
+	        allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+	        allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	ili2139_int_e708_q1: ili2139_int at 0 {
+		allwinner,pins = "PA3";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+};
+
 &reg_dldo2 {
 	regulator-min-microvolt = <1800000>;
 	regulator-max-microvolt = <1800000>;
-- 
2.10.1

^ permalink raw reply related

* [GIT PULL 1/3] ARM: soc: exynos: Drivers for v4.9
From: Kukjin Kim @ 2016-10-11  0:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <53745281-AF17-4A3A-8BB5-63EED3563298@gmail.com>

2016. 10. 3. 21:19 Kukjin Kim <kgene.kim@gmail.com> wrote:

+ my samsung email

> 2016. 10. 3. 15:48 Krzysztof Kozlowski <krzk@kernel.org> wrote:
> 
>>>> On Sun, Oct 02, 2016 at 05:25:07PM -0700, Olof Johansson wrote:
>>>>> On Mon, Sep 19, 2016 at 8:53 AM, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>>>>> On Mon, Sep 19, 2016 at 05:02:40PM +0200, Arnd Bergmann wrote:
>>>>>> On Sunday, September 18, 2016 6:39:46 PM CEST Krzysztof Kozlowski wrote:
>>>>>> Samsung drivers/soc update for v4.9:
>>>>>> 1. Allow compile testing of exynos-mct clocksource driver on ARM64.
>>>>>> 2. Document Exynos5433 PMU compatible (already used by clkout driver and more
>>>>>>  will be coming soon).
>>>>> 
>>>>> Pulled into next/drivers, thanks
>>>>> 
>>>>> Just for my understanding: why do we need the exynos-mct driver on ARM64
>>>>> but not the delay-timer portion of it?
>>>> 
>>>> I think we want all of it but Doug's optimization 3252a646aa2c
>>>> ("clocksource: exynos_mct: Only use 32-bits where possible") is not
>>>> ARM64 friendly. One way of dealing with it would be to prepare two
>>>> versions of exynos4_read_current_timer(). One reading only lower 32-bit
>>>> value for ARMv7 and second (slow) reading lower and upper for ARMv8.
>>>> 
>>>>> 
>>>>> Is there an advantage in using MCT over the architected timer on these
>>>>> chips? If so, should we also have a way to use it as the delay timer?
>>>> 
>>>> No, there is no real advantage... except that the SoC has some
>>>> interesting "characteristics"... The timers are tightly coupled. Very
>>>> tightly. I spent a lot of time and failed to boot my ARMv8 board without
>>>> some MCT magic.
>>> 
>>> What kind of magic is that?
>> 
>> Most notably: the arch timer starts when MCT forward running counter
>> starts. Without kicking MCT, the arch timer seems to be frozen.
>> 
>>> I can understand that needing the MCT for
>>> some system-level timer functionality might be true (wakeups, etc),
>>> but for system timesource avoiding the MMIO timer and using the arch
>>> ones is a substantial performance improvement for gettimeofday() and
>>> friends.
>>> 
>>> There was extensive discussion last year over using arch timers on
>>> 5420/5422, and it fizzled out with vague comments about something not
>>> working right between A15/A7 on b.L. hardware. I'm presuming whatever
>>> implementation details of that SoC has since been fixed on later chips
>>> (including v8). Any chance you can confirm? It'd be very nice to leave
>>> MCT behind on v8 as a system time source.
>> 
>> Unfortunately, I cannot confirm this, at least on Exynos5433 (ARMv8). I
>> played with arch and MCT timers on it and failed to get the
>> arch-timer-only setup working. I did not have access to newer Exynos
>> designs (Exynos 7) so I do not know how it works there.
> 
> Hi guys,
> 
> I know what Olof want to know and actually several days ago someone asked me about that. As you guys talked, a couple of years ago there were some discussions...BTW I need to contact to hardware designer before let you guys know because something needs to be confirmed by them even I know roughly.
> 
> Note I'm in vacation with my family. Will be back on this in several days with exact information.
> 
> BRs,
> Kukjin

^ permalink raw reply

* [GIT PULL 1/3] ARM: soc: exynos: Drivers for v4.9
From: Kukjin Kim @ 2016-10-11  0:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50A42280-0A39-44E3-8E35-C24031EB4DF0@gmail.com>

Kukjin Kim wrote:

- Krzysztof's samsung email because he is not using now

> 
> 2016. 10. 3. 21:19 Kukjin Kim <kgene.kim@gmail.com> wrote:
> 
> + my samsung email
> 
> > 2016. 10. 3. 15:48 Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >
> >>>> On Sun, Oct 02, 2016 at 05:25:07PM -0700, Olof Johansson wrote:
> >>>>> On Mon, Sep 19, 2016 at 8:53 AM, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >>>>>> On Mon, Sep 19, 2016 at 05:02:40PM +0200, Arnd Bergmann wrote:
> >>>>>> On Sunday, September 18, 2016 6:39:46 PM CEST Krzysztof Kozlowski wrote:
> >>>>>> Samsung drivers/soc update for v4.9:
> >>>>>> 1. Allow compile testing of exynos-mct clocksource driver on ARM64.
> >>>>>> 2. Document Exynos5433 PMU compatible (already used by clkout
> >>>>>> driver and more  will be coming soon).
> >>>>>
> >>>>> Pulled into next/drivers, thanks
> >>>>>
> >>>>> Just for my understanding: why do we need the exynos-mct driver on
> >>>>> ARM64 but not the delay-timer portion of it?
> >>>>
> >>>> I think we want all of it but Doug's optimization 3252a646aa2c
> >>>> ("clocksource: exynos_mct: Only use 32-bits where possible") is not
> >>>> ARM64 friendly. One way of dealing with it would be to prepare two
> >>>> versions of exynos4_read_current_timer(). One reading only lower
> >>>> 32-bit value for ARMv7 and second (slow) reading lower and upper for ARMv8.
> >>>>
> >>>>>
> >>>>> Is there an advantage in using MCT over the architected timer on
> >>>>> these chips? If so, should we also have a way to use it as the delay timer?
> >>>>
> >>>> No, there is no real advantage... except that the SoC has some
> >>>> interesting "characteristics"... The timers are tightly coupled.
> >>>> Very tightly. I spent a lot of time and failed to boot my ARMv8
> >>>> board without some MCT magic.
> >>>
> >>> What kind of magic is that?
> >>
> >> Most notably: the arch timer starts when MCT forward running counter
> >> starts. Without kicking MCT, the arch timer seems to be frozen.
> >>
> >>> I can understand that needing the MCT for some system-level timer
> >>> functionality might be true (wakeups, etc),

Yes correct, the MCT is designed for the power consumption related
functionalities such as cluster power down

> >>> but for system
> >>> timesource avoiding the MMIO timer and using the arch ones is a
> >>> substantial performance improvement for gettimeofday() and friends.
> >>>

At this moment, we can use the ARM arch timers as clocksource so I think
no performance degradation (some latency?) with using the CP15 access for
the gettimeofday() and friends

> >>> There was extensive discussion last year over using arch timers on
> >>> 5420/5422, and it fizzled out with vague comments about something
> >>> not working right between A15/A7 on b.L. hardware.

Current Exynos SoCs including ARMv8 architecture based have no hardware
something which means 'not working right'

> >>> I'm presuming
> >>> whatever implementation details of that SoC has since been fixed on
> >>> later chips (including v8). Any chance you can confirm? It'd be very
> >>> nice to leave MCT behind on v8 as a system time source.

It is depending on system level design architecture. If we don't need to
support some power mode such as cluster power down, we can use arch timers
without the MCT but actual product needed to support it for power consumption.

Let me add some comments.
According to the ARM architecture design, the ARM arch timers require toggle
from outside of the core as timer source and we're using the MCT for it. And
we can use the ARM arch timers as clocksource not the MCT on current Exynos.

> >> Unfortunately, I cannot confirm this, at least on Exynos5433 (ARMv8).
> >> I played with arch and MCT timers on it and failed to get the
> >> arch-timer-only setup working. I did not have access to newer Exynos
> >> designs (Exynos 7) so I do not know how it works there.
> >
> > Hi guys,
> >
> > I know what Olof want to know and actually several days ago someone asked me about that. As you guys
> talked, a couple of years ago there were some discussions...BTW I need to contact to hardware designer
> before let you guys know because something needs to be confirmed by them even I know roughly.
> >
> > Note I'm in vacation with my family. Will be back on this in several days with exact information.
> >
> > BRs,
> > Kukjin

k-gene

^ permalink raw reply

* [PATCH 3/3] mtd: s3c2410: parse the device configuration from OF node
From: Sergio Prado @ 2016-10-11  1:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161007162810.GB4222@kozik-lap>

On Fri, Oct 07, 2016 at 07:28:10PM +0300, Krzysztof Kozlowski wrote:

> > +struct s3c24XX_nand_devtype_data {
> > +	enum s3c_cpu_type type;
> > +};
> > +
> > +struct s3c24XX_nand_devtype_data s3c2410_nand_devtype_data = {
> > +	.type = TYPE_S3C2410,
> > +};
> > +
> > +struct s3c24XX_nand_devtype_data s3c2412_nand_devtype_data = {
> > +	.type = TYPE_S3C2412,
> > +};
> > +
> > +struct s3c24XX_nand_devtype_data s3c2440_nand_devtype_data = {
> > +	.type = TYPE_S3C2440,
> > +};
> > +
> > +struct s3c24XX_nand_devtype_data s3c6400_nand_devtype_data = {
> > +	.type = TYPE_S3C2412,
> 
> All of these look like candidate for static const.
> 
> Additionally you are not actually differentiating between s3c2412 and
> s3c64xx so I think there is not need of samsung,s3c6400-nand compatible.
> Just use existing one.
> 
> Best regards,
> Krzysztof

You are right. I'll review and send V2.

Best regards,

Sergio Prado

^ permalink raw reply


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