* Re: [PATCH v4 07/10] mfd: axp20x: add axp20x-regulator cell for AXP803
From: icenowy-h8G6r0blFSE @ 2017-04-25 5:47 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Thomas Gleixner, Rob Herring, Maxime Ripard, Lee Jones,
Liam Girdwood, linux-kernel, devicetree, linux-arm-kernel,
linux-sunxi
In-Reply-To: <CAGb2v673CL6TaZxkNR9SZDiG5G3cMqU1-=XeMj5gyDbQq4YzVA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
在 2017-04-25 10:17,Chen-Yu Tsai 写道:
> On Tue, Apr 25, 2017 at 12:01 AM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> wrote:
>> As axp20x-regulator now supports AXP803, add a cell for it.
>>
>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
>> Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
>> ---
>> Changes in v4:
>> - Added a trailing comma for new cell, for easier further cell
>> addition.
>> Changes in v3:
>> - Make the new cell one-liner.
>>
>> drivers/mfd/axp20x.c | 3 ++-
>> drivers/regulator/axp20x-regulator.c | 6 +++---
>
> Squashed in wrong patch?
Oh seems so...
>
> ChenYu
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [PATCH] ARM: dts: Add devicetree for the Raspberry Pi 3, for arm32 (v5)
From: Florian Fainelli @ 2017-04-25 4:14 UTC (permalink / raw)
To: Eric Anholt, Lee Jones, Florian Fainelli, Olof Johansson,
Rob Herring, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stefan Wahren,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Gerd Hoffmann
In-Reply-To: <20170424200037.25615-1-eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
On 04/24/2017 01:00 PM, Eric Anholt wrote:
> Raspbian and Fedora have decided to support the Pi3 in 32-bit mode for
> now, so it's useful to be able to test that mode on an upstream
> kernel. It's also been useful for me to use the same board for 32-bit
> and 64-bit development.
>
> Signed-off-by: Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
> ---
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/bcm2837-rpi-3.b.dts | 1 +
> 2 files changed, 2 insertions(+)
> create mode 100644 arch/arm/boot/dts/bcm2837-rpi-3.b.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 011808490fed..eded842d9978 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -72,6 +72,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
> bcm2835-rpi-b-plus.dtb \
> bcm2835-rpi-a-plus.dtb \
> bcm2836-rpi-2-b.dtb \
> + bcm2837-rpi-3-b.dtb \
> bcm2835-rpi-zero.dtb
> dtb-$(CONFIG_ARCH_BCM_5301X) += \
> bcm4708-asus-rt-ac56u.dtb \
> diff --git a/arch/arm/boot/dts/bcm2837-rpi-3.b.dts b/arch/arm/boot/dts/bcm2837-rpi-3.b.dts
> new file mode 100644
> index 000000000000..8c8aa4d1e9b3
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm2837-rpi-3.b.dts
> @@ -0,0 +1 @@
> +#include "arm64/broadcom/bcm2837-rpi-3.b.dts"
Sounds like this should be
../arm64/boot/dts/broadcom/bcm2837-rpi-3.b.dts are reported by the
kbuild test robot?
--
Florian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] ARM: dts: Add devicetree for the Raspberry Pi 3, for arm32 (v5)
From: kbuild test robot @ 2017-04-25 3:56 UTC (permalink / raw)
Cc: kbuild-all-JC7UmRfGjtg, Lee Jones, Florian Fainelli,
Olof Johansson, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stefan Wahren,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Gerd Hoffmann,
Eric Anholt
In-Reply-To: <20170424200037.25615-1-eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1321 bytes --]
Hi Eric,
[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.11-rc8 next-20170424]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Eric-Anholt/ARM-dts-Add-devicetree-for-the-Raspberry-Pi-3-for-arm32-v5/20170425-063618
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm-at91_dt_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm
All errors (new ones prefixed by >>):
>> arch/arm/boot/dts/bcm2837-rpi-3.b.dts:1:46: fatal error: arm64/broadcom/bcm2837-rpi-3.b.dts: No such file or directory
#include "arm64/broadcom/bcm2837-rpi-3.b.dts"
^
compilation terminated.
vim +1 arch/arm/boot/dts/bcm2837-rpi-3.b.dts
> 1 #include "arm64/broadcom/bcm2837-rpi-3.b.dts"
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 22403 bytes --]
^ permalink raw reply
* Re: [PATCH v3 2/2] Input: add support for the STMicroelectronics FingerTip touchscreen
From: Andi Shyti @ 2017-04-25 2:31 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring
Cc: Javier Martinez Canillas, Andrzej Hajda, Chanwoo Choi,
linux-input-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andi Shyti
In-Reply-To: <20170327130743.27783-3-andi.shyti-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Hi Dmitry,
again, kindly ping. This patch has been posted on March 27th and
this is the third time I ask you a feedback about it.
Please let me know,
Andi
On Mon, Mar 27, 2017 at 10:07:43PM +0900, Andi Shyti wrote:
> The stmfts (ST-Microelectronics FingerTip S) touchscreen device
> is a capacitive multi-touch controller mainly for mobile use.
>
> It's connected through i2c bus at the address 0x49 and it
> interfaces with userspace through input event interface.
>
> At the current state it provides a touchscreen multitouch
> functionality up to 10 fingers. Each finger is enumerated with a
> distinctive id (from 0 to 9).
>
> If enabled the device can support single "touch" hovering, by
> providing three coordinates, x, y and distance.
>
> It is possible to select the touchkey functionality which
> provides a basic two keys interface for "home" and "back" menu,
> typical in mobile phones.
>
> Signed-off-by: Andi Shyti <andi.shyti-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
> drivers/input/touchscreen/Kconfig | 12 +
> drivers/input/touchscreen/Makefile | 1 +
> drivers/input/touchscreen/stmfts.c | 805 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 818 insertions(+)
> create mode 100644 drivers/input/touchscreen/stmfts.c
>
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 33c62e5de4fa..f8631c64290d 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -1114,6 +1114,18 @@ config TOUCHSCREEN_ST1232
> To compile this driver as a module, choose M here: the
> module will be called st1232_ts.
>
> +config TOUCHSCREEN_STMFTS
> + tristate "STMicroelectronics STMFTS touchscreen"
> + depends on I2C
> + depends on INPUT
> + depends on LEDS_CLASS
> + help
> + Say Y here if you want support for STMicroelectronics
> + STMFTS touchscreen.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called stmfts.
> +
> config TOUCHSCREEN_STMPE
> tristate "STMicroelectronics STMPE touchscreens"
> depends on MFD_STMPE
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index 18e476948e44..6badce87037b 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -67,6 +67,7 @@ obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
> obj-$(CONFIG_TOUCHSCREEN_SILEAD) += silead.o
> obj-$(CONFIG_TOUCHSCREEN_SIS_I2C) += sis_i2c.o
> obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o
> +obj-$(CONFIG_TOUCHSCREEN_STMFTS) += stmfts.o
> obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o
> obj-$(CONFIG_TOUCHSCREEN_SUN4I) += sun4i-ts.o
> obj-$(CONFIG_TOUCHSCREEN_SUR40) += sur40.o
> diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
> new file mode 100644
> index 000000000000..2e18b1456f42
> --- /dev/null
> +++ b/drivers/input/touchscreen/stmfts.c
> @@ -0,0 +1,805 @@
> +/*
> + * Copyright (c) 2017 Samsung Electronics Co., Ltd.
> + * Author: Andi Shyti <andi.shyti-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * STMicroelectronics FTS Touchscreen device driver
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/i2c.h>
> +#include <linux/input/mt.h>
> +#include <linux/input/touchscreen.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/leds.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +
> +/* I2C commands */
> +#define STMFTS_READ_INFO 0x80
> +#define STMFTS_READ_STATUS 0x84
> +#define STMFTS_READ_ONE_EVENT 0x85
> +#define STMFTS_READ_ALL_EVENT 0x86
> +#define STMFTS_LATEST_EVENT 0x87
> +#define STMFTS_SLEEP_IN 0x90
> +#define STMFTS_SLEEP_OUT 0x91
> +#define STMFTS_MS_MT_SENSE_OFF 0x92
> +#define STMFTS_MS_MT_SENSE_ON 0x93
> +#define STMFTS_SS_HOVER_SENSE_OFF 0x94
> +#define STMFTS_SS_HOVER_SENSE_ON 0x95
> +#define STMFTS_MS_KEY_SENSE_OFF 0x9a
> +#define STMFTS_MS_KEY_SENSE_ON 0x9b
> +#define STMFTS_SYSTEM_RESET 0xa0
> +#define STMFTS_CLEAR_EVENT_STACK 0xa1
> +#define STMFTS_FULL_FORCE_CALIBRATION 0xa2
> +#define STMFTS_MS_CX_TUNING 0xa3
> +#define STMFTS_SS_CX_TUNING 0xa4
> +
> +/* events */
> +#define STMFTS_EV_NO_EVENT 0x00
> +#define STMFTS_EV_MULTI_TOUCH_DETECTED 0x02
> +#define STMFTS_EV_MULTI_TOUCH_ENTER 0x03
> +#define STMFTS_EV_MULTI_TOUCH_LEAVE 0x04
> +#define STMFTS_EV_MULTI_TOUCH_MOTION 0x05
> +#define STMFTS_EV_HOVER_ENTER 0x07
> +#define STMFTS_EV_HOVER_LEAVE 0x08
> +#define STMFTS_EV_HOVER_MOTION 0x09
> +#define STMFTS_EV_KEY_STATUS 0x0e
> +#define STMFTS_EV_ERROR 0x0f
> +#define STMFTS_EV_CONTROLLER_READY 0x10
> +#define STMFTS_EV_SLEEP_OUT_CONTROLLER_READY 0x11
> +#define STMFTS_EV_STATUS 0x16
> +#define STMFTS_EV_DEBUG 0xdb
> +
> +/* multi touch related event masks */
> +#define STMFTS_MASK_EVENT_ID 0x0f
> +#define STMFTS_MASK_TOUCH_ID 0xf0
> +#define STMFTS_MASK_LEFT_EVENT 0x0f
> +#define STMFTS_MASK_X_MSB 0x0f
> +#define STMFTS_MASK_Y_LSB 0xf0
> +
> +/* key related event masks */
> +#define STMFTS_MASK_KEY_NO_TOUCH 0x00
> +#define STMFTS_MASK_KEY_MENU 0x01
> +#define STMFTS_MASK_KEY_BACK 0x02
> +
> +#define STMFTS_EVENT_SIZE 8
> +#define STMFTS_STACK_DEPTH 32
> +#define STMFTS_DATA_MAX_SIZE (STMFTS_EVENT_SIZE * STMFTS_STACK_DEPTH)
> +#define STMFTS_MAX_FINGERS 10
> +#define STMFTS_DEV_NAME "stmfts"
> +
> +enum stmfts_regulators {
> + STMFTS_REGULATOR_VDD,
> + STMFTS_REGULATOR_AVDD,
> +};
> +
> +struct stmfts_data {
> + struct i2c_client *client;
> + struct input_dev *input;
> + struct led_classdev led_cdev;
> + struct mutex mutex;
> +
> + struct touchscreen_properties prop;
> +
> + struct regulator_bulk_data regulators[2];
> +
> + /* ledvdd will be used also to check
> + * whether the LED is supported
> + */
> + struct regulator *ledvdd;
> +
> + u16 chip_id;
> + u8 chip_ver;
> + u16 fw_ver;
> + u8 config_id;
> + u8 config_ver;
> +
> + u8 data[STMFTS_DATA_MAX_SIZE];
> +
> + struct completion signal;
> +
> + bool use_key;
> + bool led_status;
> + bool hover_enabled;
> + bool running;
> +};
> +
> +static int stmfts_read_i2c_block_data(struct stmfts_data *sdata)
> +{
> + struct i2c_msg msgs[2];
> + u8 cmd = STMFTS_READ_ALL_EVENT;
> +
> + msgs[0].addr = sdata->client->addr;
> + msgs[0].flags = 0;
> + msgs[0].len = 1;
> + msgs[0].buf = &cmd;
> +
> + msgs[1].addr = sdata->client->addr;
> + msgs[1].flags = I2C_M_RD;
> + msgs[1].len = STMFTS_DATA_MAX_SIZE - STMFTS_EVENT_SIZE;
> + msgs[1].buf = sdata->data + STMFTS_EVENT_SIZE;
> +
> + return i2c_transfer(sdata->client->adapter, msgs, ARRAY_SIZE(msgs));
> +}
> +
> +static void stmfts_brightness_set(struct led_classdev *led_cdev,
> + enum led_brightness value)
> +{
> + struct stmfts_data *sdata = container_of(led_cdev,
> + struct stmfts_data, led_cdev);
> +
> + if (value == sdata->led_status || !sdata->ledvdd)
> + return;
> +
> + if (!value) {
> + regulator_disable(sdata->ledvdd);
> + } else {
> + int err = regulator_enable(sdata->ledvdd);
> +
> + if (err)
> + dev_warn(&sdata->client->dev,
> + "failed to disable ledvdd regulator\n");
> + }
> +
> + sdata->led_status = value;
> +}
> +
> +static enum led_brightness stmfts_brightness_get(struct led_classdev *led_cdev)
> +{
> + struct stmfts_data *sdata = container_of(led_cdev,
> + struct stmfts_data, led_cdev);
> +
> + return !!regulator_is_enabled(sdata->ledvdd);
> +}
> +
> +static void stmfts_parse_event(struct stmfts_data *sdata)
> +{
> + u8 id, t_id;
> + u16 x, y, z, maj, min, orientation, area;
> + u8 *event;
> + int i;
> +
> + for (i = 0; i < STMFTS_STACK_DEPTH; i++) {
> + event = &sdata->data[i*STMFTS_EVENT_SIZE];
> +
> + id = event[0] & STMFTS_MASK_EVENT_ID;
> + t_id = (event[0] & STMFTS_MASK_TOUCH_ID) >> 4;
> +
> + switch (id) {
> + case STMFTS_EV_NO_EVENT:
> + return;
> +
> + case STMFTS_EV_MULTI_TOUCH_ENTER:
> + case STMFTS_EV_MULTI_TOUCH_LEAVE:
> + case STMFTS_EV_MULTI_TOUCH_MOTION:
> + if (id == STMFTS_EV_MULTI_TOUCH_ENTER)
> + input_mt_report_slot_state(sdata->input,
> + MT_TOOL_FINGER, true);
> + else if (id == STMFTS_EV_MULTI_TOUCH_LEAVE)
> + input_mt_report_slot_state(sdata->input,
> + MT_TOOL_FINGER, false);
> +
> + x = event[1] | ((event[2] & STMFTS_MASK_X_MSB) << 8);
> + y = (event[2] >> 4) | (event[3] << 4);
> +
> + maj = event[4];
> + min = event[5];
> + orientation = event[6];
> + area = event[7];
> +
> + input_mt_slot(sdata->input, t_id);
> + input_report_abs(sdata->input, ABS_MT_POSITION_X, x);
> + input_report_abs(sdata->input, ABS_MT_POSITION_Y, y);
> + input_report_abs(sdata->input, ABS_MT_TOUCH_MAJOR, maj);
> + input_report_abs(sdata->input, ABS_MT_TOUCH_MINOR, min);
> + input_report_abs(sdata->input, ABS_MT_PRESSURE, area);
> + input_report_abs(sdata->input, ABS_MT_ORIENTATION,
> + orientation);
> + input_sync(sdata->input);
> +
> + break;
> +
> + case STMFTS_EV_HOVER_ENTER:
> + case STMFTS_EV_HOVER_LEAVE:
> + case STMFTS_EV_HOVER_MOTION:
> + x = (event[2] << 4) | (event[4] >> 4);
> + y = (event[3] << 4) | (event[4] & STMFTS_MASK_Y_LSB);
> + z = event[5];
> + orientation = event[6] & STMFTS_MASK_Y_LSB;
> +
> + input_report_abs(sdata->input, ABS_X, x);
> + input_report_abs(sdata->input, ABS_Y, y);
> + input_report_abs(sdata->input, ABS_DISTANCE, z);
> + input_sync(sdata->input);
> +
> + break;
> +
> + case STMFTS_EV_KEY_STATUS:
> + switch (event[2]) {
> + case 0:
> + input_report_key(sdata->input, KEY_BACK, 0);
> + input_report_key(sdata->input, KEY_MENU, 0);
> + break;
> +
> + case STMFTS_MASK_KEY_BACK:
> + input_report_key(sdata->input, KEY_BACK, 1);
> + break;
> +
> + case STMFTS_MASK_KEY_MENU:
> + input_report_key(sdata->input, KEY_MENU, 1);
> + break;
> +
> + default:
> + dev_warn(&sdata->client->dev,
> + "unknown key event\n");
> + }
> +
> + input_sync(sdata->input);
> + break;
> +
> + case STMFTS_EV_ERROR:
> + dev_warn(&sdata->client->dev,
> + "error code: 0x%x%x%x%x%x%x",
> + event[6], event[5], event[4],
> + event[3], event[2], event[1]);
> + break;
> +
> + default:
> + dev_err(&sdata->client->dev,
> + "unknown event 0x%x\n", event[0]);
> + }
> + }
> +}
> +
> +static irqreturn_t stmfts_irq_handler(int irq, void *dev)
> +{
> + struct stmfts_data *sdata = dev;
> + int ret;
> +
> + mutex_lock(&sdata->mutex);
> + ret = i2c_smbus_read_i2c_block_data(sdata->client,
> + STMFTS_READ_ONE_EVENT,
> + STMFTS_EVENT_SIZE, sdata->data);
> +
> + if (ret < 0 || ret != STMFTS_EVENT_SIZE)
> + goto exit;
> +
> + switch (sdata->data[0]) {
> + case STMFTS_EV_CONTROLLER_READY:
> + case STMFTS_EV_SLEEP_OUT_CONTROLLER_READY:
> + case STMFTS_EV_STATUS:
> + complete(&sdata->signal);
> + case STMFTS_EV_NO_EVENT:
> + case STMFTS_EV_DEBUG:
> + break;
> +
> + default:
> + if (unlikely(!sdata->input))
> + goto exit;
> +
> + ret = stmfts_read_i2c_block_data(sdata);
> + if (ret < 0)
> + goto exit;
> +
> + stmfts_parse_event(sdata);
> + }
> +
> +exit:
> + mutex_unlock(&sdata->mutex);
> + return IRQ_HANDLED;
> +}
> +
> +static int stmfts_write_and_wait(struct stmfts_data *sdata, const u8 cmd)
> +{
> + int err;
> +
> + err = i2c_smbus_write_byte(sdata->client, cmd);
> + if (err)
> + return err;
> +
> + err = wait_for_completion_timeout(&sdata->signal,
> + msecs_to_jiffies(1000));
> +
> + return !err ? -ETIMEDOUT : 0;
> +}
> +
> +static int stmfts_input_open(struct input_dev *dev)
> +{
> + int ret;
> + struct stmfts_data *sdata = input_get_drvdata(dev);
> +
> + ret = pm_runtime_get_sync(&sdata->client->dev);
> + if (ret < 0)
> + return ret;
> +
> + ret = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_ON);
> + if (ret)
> + return ret;
> +
> + mutex_lock(&sdata->mutex);
> + sdata->running = true;
> +
> + if (sdata->hover_enabled) {
> + ret = i2c_smbus_write_byte(sdata->client,
> + STMFTS_SS_HOVER_SENSE_ON);
> + if (ret)
> + dev_warn(&sdata->client->dev,
> + "failed to enable hover\n");
> + }
> + mutex_unlock(&sdata->mutex);
> +
> + if (sdata->use_key) {
> + ret = i2c_smbus_write_byte(sdata->client,
> + STMFTS_MS_KEY_SENSE_ON);
> + if (ret)
> + /* I can still use only the touch screen */
> + dev_warn(&sdata->client->dev,
> + "failed to enable touchkey\n");
> + }
> +
> + return 0;
> +}
> +
> +static void stmfts_input_close(struct input_dev *dev)
> +{
> + int ret;
> + struct stmfts_data *sdata = input_get_drvdata(dev);
> +
> + ret = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_OFF);
> + if (ret)
> + dev_warn(&sdata->client->dev,
> + "failed to disable touchscreen\n");
> +
> + mutex_lock(&sdata->mutex);
> + sdata->running = false;
> +
> + if (sdata->hover_enabled) {
> + ret = i2c_smbus_write_byte(sdata->client,
> + STMFTS_SS_HOVER_SENSE_OFF);
> + if (ret)
> + dev_warn(&sdata->client->dev,
> + "failed to disable hover\n");
> + }
> + mutex_unlock(&sdata->mutex);
> +
> + if (sdata->use_key) {
> + i2c_smbus_write_byte(sdata->client, STMFTS_MS_KEY_SENSE_OFF);
> + if (ret)
> + dev_warn(&sdata->client->dev,
> + "failed to disable touchkey\n");
> + }
> +
> + pm_runtime_put_sync(&sdata->client->dev);
> +}
> +
> +static ssize_t stmfts_sysfs_chip_id(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "0x%x\n", sdata->chip_id);
> +}
> +
> +static ssize_t stmfts_sysfs_chip_version(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "%u\n", sdata->chip_ver);
> +}
> +
> +static ssize_t stmfts_sysfs_fw_ver(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "%u\n", sdata->fw_ver);
> +}
> +
> +static ssize_t stmfts_sysfs_config_id(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "0x%x\n", sdata->config_id);
> +}
> +
> +static ssize_t stmfts_sysfs_config_version(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "%u\n", sdata->config_ver);
> +}
> +
> +static ssize_t stmfts_sysfs_read_status(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> + u8 status[4];
> + int ret;
> +
> + ret = i2c_smbus_read_i2c_block_data(sdata->client,
> + STMFTS_READ_STATUS, 4, status);
> +
> + return sprintf(buf, "0x%x\n", status[0]);
> +}
> +
> +static ssize_t stmfts_sysfs_hover_enable_read(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "%u\n", sdata->hover_enabled);
> +}
> +
> +static ssize_t stmfts_sysfs_hover_enable_write(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + unsigned long value;
> + int err;
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + if (kstrtoul(buf, 0, &value))
> + return -EINVAL;
> +
> + mutex_lock(&sdata->mutex);
> +
> + if (value & sdata->hover_enabled)
> + goto out;
> +
> + if (!sdata->running) {
> + sdata->hover_enabled = !!value;
> + goto out;
> + }
> +
> + if (value) {
> + err = i2c_smbus_write_byte(sdata->client,
> + STMFTS_SS_HOVER_SENSE_ON);
> + sdata->hover_enabled = !err;
> + } else {
> + err = i2c_smbus_write_byte(sdata->client,
> + STMFTS_SS_HOVER_SENSE_OFF);
> + sdata->hover_enabled = !!err;
> + }
> +
> + if (err)
> + dev_warn(&sdata->client->dev, "failed to %s hover\n",
> + value ? "enable" : "disable");
> +out:
> + mutex_unlock(&sdata->mutex);
> +
> + return len;
> +}
> +
> +static DEVICE_ATTR(chip_id, 0444, stmfts_sysfs_chip_id, NULL);
> +static DEVICE_ATTR(chip_version, 0444, stmfts_sysfs_chip_version, NULL);
> +static DEVICE_ATTR(fw_ver, 0444, stmfts_sysfs_fw_ver, NULL);
> +static DEVICE_ATTR(config_id, 0444, stmfts_sysfs_config_id, NULL);
> +static DEVICE_ATTR(config_version, 0444, stmfts_sysfs_config_version, NULL);
> +static DEVICE_ATTR(status, 0444, stmfts_sysfs_read_status, NULL);
> +static DEVICE_ATTR(hover_enable, 0644, stmfts_sysfs_hover_enable_read,
> + stmfts_sysfs_hover_enable_write);
> +
> +static struct attribute *stmfts_sysfs_attrs[] = {
> + &dev_attr_chip_id.attr,
> + &dev_attr_chip_version.attr,
> + &dev_attr_fw_ver.attr,
> + &dev_attr_config_id.attr,
> + &dev_attr_config_version.attr,
> + &dev_attr_status.attr,
> + &dev_attr_hover_enable.attr,
> + NULL
> +};
> +
> +static struct attribute_group stmfts_attribute_group = {
> + .attrs = stmfts_sysfs_attrs
> +};
> +
> +static int stmfts_power_on(struct stmfts_data *sdata)
> +{
> + int err;
> + u8 reg[8];
> +
> + err = regulator_bulk_enable(ARRAY_SIZE(sdata->regulators),
> + sdata->regulators);
> + if (err)
> + return err;
> +
> + /*
> + * the datasheet does not specify the power on time, but considering
> + * that the reset time is < 10ms, I sleep 20ms to be sure
> + */
> + msleep(20);
> +
> + err = i2c_smbus_read_i2c_block_data(sdata->client,
> + STMFTS_READ_INFO, 8, reg);
> + if (err < 0)
> + return err;
> + if (err != 8)
> + return -EIO;
> +
> + sdata->chip_id = (reg[6] << 8) | reg[7];
> + sdata->chip_ver = reg[0];
> + sdata->fw_ver = (reg[2] << 8) | reg[3];
> + sdata->config_id = reg[4];
> + sdata->config_ver = reg[5];
> +
> + reinit_completion(&sdata->signal);
> +
> + enable_irq(sdata->client->irq);
> + err = stmfts_write_and_wait(sdata, STMFTS_SYSTEM_RESET);
> + if (err)
> + return err;
> +
> + err = stmfts_write_and_wait(sdata, STMFTS_SLEEP_OUT);
> + if (err)
> + return err;
> +
> + /* optional tuning */
> + err = stmfts_write_and_wait(sdata, STMFTS_MS_CX_TUNING);
> + if (err)
> + dev_warn(&sdata->client->dev, "failed to perform mutual auto tune\n");
> +
> + /* optional tuning */
> + err = stmfts_write_and_wait(sdata, STMFTS_SS_CX_TUNING);
> + if (err)
> + dev_warn(&sdata->client->dev, "failed to perform self auto tune\n");
> +
> + err = stmfts_write_and_wait(sdata, STMFTS_FULL_FORCE_CALIBRATION);
> + if (err)
> + return err;
> +
> + /* at this point no one is using the touchscreen
> + * and I don't really care about the return value
> + */
> + i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
> +
> + return 0;
> +}
> +
> +static void stmfts_power_off(void *data)
> +{
> + struct stmfts_data *sdata = data;
> +
> + disable_irq(sdata->client->irq);
> + regulator_bulk_disable(ARRAY_SIZE(sdata->regulators),
> + sdata->regulators);
> +}
> +
> +/* This function is void because I don't want to prevent using the touch key
> + * only because the LEDs don't get registered
> + */
> +static int stmfts_enable_led(struct stmfts_data *sdata)
> +{
> + int err;
> +
> + /* get the regulator for powering the leds on */
> + sdata->ledvdd = devm_regulator_get(&sdata->client->dev, "ledvdd");
> + if (IS_ERR(sdata->ledvdd))
> + return PTR_ERR(sdata->ledvdd);
> +
> + sdata->led_cdev.name = STMFTS_DEV_NAME;
> + sdata->led_cdev.max_brightness = LED_ON;
> + sdata->led_cdev.brightness = LED_OFF;
> + sdata->led_cdev.brightness_set = stmfts_brightness_set;
> + sdata->led_cdev.brightness_get = stmfts_brightness_get;
> +
> + err = devm_led_classdev_register(&sdata->client->dev, &sdata->led_cdev);
> + if (err) {
> + devm_regulator_put(sdata->ledvdd);
> + return err;
> + }
> +
> + return 0;
> +}
> +
> +static int stmfts_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + int err;
> + struct stmfts_data *sdata;
> +
> + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
> + I2C_FUNC_SMBUS_BYTE_DATA |
> + I2C_FUNC_SMBUS_I2C_BLOCK))
> + return -ENODEV;
> +
> + if (!client->dev.of_node)
> + return -ENOENT;
> +
> + sdata = devm_kzalloc(&client->dev, sizeof(*sdata), GFP_KERNEL);
> + if (!sdata)
> + return -ENOMEM;
> +
> + i2c_set_clientdata(client, sdata);
> +
> + mutex_init(&sdata->mutex);
> +
> + sdata->regulators[STMFTS_REGULATOR_VDD].supply = "vdd";
> + sdata->regulators[STMFTS_REGULATOR_AVDD].supply = "avdd";
> + err = devm_regulator_bulk_get(&client->dev,
> + ARRAY_SIZE(sdata->regulators), sdata->regulators);
> + if (err)
> + return err;
> +
> + err = devm_add_action_or_reset(&client->dev, stmfts_power_off, sdata);
> + if (err)
> + return err;
> +
> + sdata->client = client;
> +
> + init_completion(&sdata->signal);
> +
> + /*
> + * Do not enable interrupts by default.
> + * One possible case when an IRQ can be already rased is e.g. if the
> + * regulator is set as always on and the stmfts device sends an IRQ as
> + * soon as it gets powered, de-synchronizing the power on sequence.
> + * During power on, the device will be reset and all the initialization
> + * IRQ will be resent.
> + */
> + irq_set_status_flags(client->irq, IRQ_NOAUTOEN);
> + err = devm_request_threaded_irq(&client->dev, client->irq,
> + NULL, stmfts_irq_handler,
> + IRQF_ONESHOT | IRQF_TRIGGER_LOW,
> + "stmfts_irq", sdata);
> + if (err)
> + return err;
> +
> + dev_info(&client->dev, "initializing ST-Microelectronics FTS...\n");
> + err = stmfts_power_on(sdata);
> + if (err)
> + return err;
> +
> + sdata->use_key = of_property_read_bool(client->dev.of_node,
> + "touch-key-connected");
> +
> + sdata->input = devm_input_allocate_device(&client->dev);
> + if (!sdata->input)
> + return -ENOMEM;
> +
> + sdata->input->name = STMFTS_DEV_NAME;
> + sdata->input->id.bustype = BUS_I2C;
> + sdata->input->open = stmfts_input_open;
> + sdata->input->close = stmfts_input_close;
> +
> + touchscreen_parse_properties(sdata->input, true, &sdata->prop);
> +
> + input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0,
> + sdata->prop.max_x, 0, 0);
> + input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0,
> + sdata->prop.max_y, 0, 0);
> + input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
> + input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
> + input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
> + input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
> + input_set_abs_params(sdata->input, ABS_DISTANCE, 0, 255, 0, 0);
> +
> + if (sdata->use_key) {
> + input_set_capability(sdata->input, EV_KEY, KEY_MENU);
> + input_set_capability(sdata->input, EV_KEY, KEY_BACK);
> + }
> +
> + err = input_mt_init_slots(sdata->input,
> + STMFTS_MAX_FINGERS, INPUT_MT_DIRECT);
> + if (err)
> + return err;
> +
> + input_set_drvdata(sdata->input, sdata);
> + err = input_register_device(sdata->input);
> + if (err)
> + return err;
> +
> + if (sdata->use_key) {
> + err = stmfts_enable_led(sdata);
> + if (err) {
> + /* even if the LEDs have failed to be initialized and
> + * used in the driver, I can still use the device even
> + * without LEDs. The ledvdd regulator pointer will be
> + * used as a flag.
> + */
> + dev_warn(&client->dev,
> + "unable to use touchkey leds\n");
> + sdata->ledvdd = NULL;
> + }
> + }
> +
> + err = sysfs_create_group(&sdata->client->dev.kobj,
> + &stmfts_attribute_group);
> + if (err)
> + return err;
> +
> + pm_runtime_enable(&client->dev);
> +
> + return 0;
> +}
> +
> +static int stmfts_remove(struct i2c_client *client)
> +{
> + pm_runtime_disable(&client->dev);
> + sysfs_remove_group(&client->dev.kobj, &stmfts_attribute_group);
> +
> + return 0;
> +}
> +
> +static int stmfts_runtime_suspend(struct device *dev)
> +{
> + int ret;
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
> + if (ret)
> + dev_warn(dev, "failed to suspend device\n");
> +
> + return ret;
> +}
> +
> +static int stmfts_runtime_resume(struct device *dev)
> +{
> + int ret;
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_OUT);
> + if (ret)
> + dev_err(dev, "failed to resume device\n");
> +
> + return ret;
> +}
> +
> +static int __maybe_unused stmfts_suspend(struct device *dev)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + stmfts_power_off(sdata);
> +
> + return 0;
> +}
> +
> +static int __maybe_unused stmfts_resume(struct device *dev)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return stmfts_power_on(sdata);
> +}
> +
> +static const struct dev_pm_ops stmfts_pm_ops = {
> + SET_SYSTEM_SLEEP_PM_OPS(stmfts_suspend, stmfts_resume)
> + SET_RUNTIME_PM_OPS(stmfts_runtime_suspend, stmfts_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id stmfts_of_match[] = {
> + { .compatible = "st,stmfts", },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, stmfts_of_match);
> +
> +static const struct i2c_device_id stmfts_id[] = {
> + { "stmfts", 0 },
> + { },
> +};
> +MODULE_DEVICE_TABLE(i2c, stmfts_id);
> +
> +static struct i2c_driver stmfts_driver = {
> + .driver = {
> + .name = STMFTS_DEV_NAME,
> + .of_match_table = of_match_ptr(stmfts_of_match),
> + .pm = &stmfts_pm_ops,
> + },
> + .probe = stmfts_probe,
> + .remove = stmfts_remove,
> + .id_table = stmfts_id,
> +};
> +
> +module_i2c_driver(stmfts_driver);
> +
> +MODULE_AUTHOR("Andi Shyti <andi.shyti-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>");
> +MODULE_DESCRIPTION("STMicroelectronics FTS Touch Screen");
> +MODULE_LICENSE("GPL v2");
> --
> 2.11.0
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v7 4/5] i2c: aspeed: added driver for Aspeed I2C
From: Benjamin Herrenschmidt @ 2017-04-25 2:21 UTC (permalink / raw)
To: Brendan Higgins, wsa, robh+dt, mark.rutland, tglx, jason,
marc.zyngier, joel, vz, mouse, clg
Cc: linux-i2c, devicetree, linux-kernel, openbmc
In-Reply-To: <20170424181818.2754-5-brendanhiggins@google.com>
On Mon, 2017-04-24 at 11:18 -0700, Brendan Higgins wrote:
> +static int __aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus,
> + struct platform_device *pdev)
> +{
Minor nit ... I'm really not fan of those underscores.
We use __ functions in some cases in the kernel for low level
helpers, usually when it's a low level variant of an existing
function or an "unlocked" variant, but I don't think generalizing
it to pretty much everything in the driver is worthwhile here.
If you want to be explicit about locking, I would suggest you
use a comment in front of the function explaining if it
expects to be called with the lock held.
We tend to only do that when *both* functions exist and one is
implemented in term of the other.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH v6 4/5] i2c: aspeed: added driver for Aspeed I2C
From: Benjamin Herrenschmidt @ 2017-04-25 2:19 UTC (permalink / raw)
To: Brendan Higgins
Cc: Wolfram Sang, Rob Herring, Mark Rutland, Thomas Gleixner,
Jason Cooper, Marc Zyngier, Joel Stanley, Vladimir Zapolskiy,
Kachalov Anton, Cédric Le Goater, linux-i2c, devicetree,
Linux Kernel Mailing List, OpenBMC Maillist
In-Reply-To: <CAFd5g45DQZz99y59AY-4465qnM+tRv6+bDdGQqS6VYHEfRfjDg@mail.gmail.com>
On Mon, 2017-04-24 at 11:56 -0700, Brendan Higgins wrote:
> > > +struct aspeed_i2c_bus {
> > > + struct i2c_adapter adap;
> > > + struct device *dev;
> > > + void __iomem *base;
> > > + /* Synchronizes I/O mem access to base. */
> > > + spinlock_t lock;
> >
> > I am not entirely convinced we need that lock. The i2c core will
> > take a mutex protecting all operations on the bus. So we only need
> > to synchronize between our "xfer" code and our interrupt handler.
>
> You are right if both having slave and master active at the same time
> was not possible; however, it is.
Right, I somewhat forgot about the slave case.
...
> > Some of those error states probably also warrant a reset of the
> > controller,
> > I think aspeed does that in the SDK.
>
> For timeout and cmd_err, I do not see any argument against it; it
> sounds like we are in a very messed up, very unknown state, so full
> reset is probably the best last resort.
Yup.
> For SDA staying pulled down, I
> think we can say with reasonable confidence that some device on our
> bus is behaving very badly and I am not convinced that resetting the
> controller is likely to do anything to help;
Right. Hammering with STOPs and pray ...
> that being said, I really
> do not have any good ideas to address that. So maybe praying and
> resetting the controller is *the most reasonable thing to do.* I
> would like to know what you think we should do in that case.
Well, there's a (small ?) chance that it's a controller bug asserting
the line so ... but there's little we can do if not.
> While I was thinking about this I also realized that the SDA line
> check after recovery happens in the else branch, but SCL line check
> does not happen after we attempt to STOP if SCL is hung. If we decide
> to make special note SDA being hung by a device that won't let go, we
> might want to make a special note that SCL is hung by a device that
> won't let go. Just a thought.
Maybe. Or just "unrecoverable error"... hopefully these don't happen
too often ... We had cases of a TPM misbehaving like that.
> > > +out:
>
> ...
> > What about I2C_M_NOSTART ?
> >
> > Not that I've ever seen it used... ;-)
>
> Right now I am not doing any of the protocol mangling options, but I
> can add them in if you think it is important for initial support.
No, not important, we can add that later if it ever becomes useful.
...
> > In general, you always ACK all interrupts first. Then you handle
> > the bits you have harvested.
> >
>
> The documentation says to ACK the interrupt after handling in the RX
> case:
>
> <<<
> S/W needs to clear this status bit to allow next data receiving.
> > > >
>
> I will double check with Ryan to make sure TX works the same way.
>
> > > + if (irq_status & ASPEED_I2CD_INTR_ERROR ||
> > > + (!bus->msgs && bus->master_state !=
> > > ASPEED_I2C_MASTER_STOP)) {
>
> ...
> >
> > I would set master_state to "RECOVERY" (new state ?) and ensure
> > those things are caught if they happen outside of a recovery.
I replied privately ... as long as we ack before we start a new command
we should be ok but we shouldn't ack after.
Your latest patch still does that. It will do things like start a STOP
command *then* ack the status bits. I'm pretty sure that's bogus.
That way it's a lot simpler to simply move the
writel(irq_status, bus->base + ASPEED_I2C_INTR_STS_REG);
To either right after the readl of the status reg at the beginning of
aspeed_i2c_master_irq().
I would be very surprised if that didn't work properly and wasn't much
safer than what you are currently doing.
> Let me know if you still think we need a "RECOVERY" state.
The way you just switch to stop state and store the error for later
should work I think.
> >
> > > + if (bus->master_state == ASPEED_I2C_MASTER_START) {
>
> ...
> >
> > > + dev_dbg(bus->dev,
> > > + "no slave present at %02x", msg-
> > > >addr);
> > > + status_ack |= ASPEED_I2CD_INTR_TX_NAK;
> > > + bus->cmd_err = -EIO;
> > > + do_stop(bus);
> > > + goto out_no_complete;
> > > + } else {
> > > + status_ack |= ASPEED_I2CD_INTR_TX_ACK;
> > > + if (msg->flags & I2C_M_RD)
> > > + bus->master_state =
> > > ASPEED_I2C_MASTER_RX;
> > > + else
> > > + bus->master_state =
> > > ASPEED_I2C_MASTER_TX_FIRST;
> >
> > What about the SMBUS_QUICK case ? (0-len transfer). Do we need
> > to handle this here ? A quick look at the TX_FIRST case makes
> > me think we are ok there but I'm not sure about the RX case.
>
> I did not think that there is an SMBUS_QUICK RX. Could you point me
> to an example?
Not so much an RX, it's more like you are sending a 1-bit data in
the place of the Rd/Wr bit. So you have a read with a lenght of 0,
I don't think in that case you should set ASPEED_I2CD_M_RX_CMD in
__aspeed_i2c_do_start
> > I'm not sure the RX case is tight also. What completion does the
> > HW give you for the address cycle ? Won't you get that before it
> > has received the first character ? IE. You fall through to
> > the read case of the state machine with the read potentially
> > not complete yet no ?
>
> ...
> > > + case ASPEED_I2C_MASTER_RX:
> > > + if (!(irq_status & ASPEED_I2CD_INTR_RX_DONE)) {
> > > + dev_err(bus->dev, "master failed to RX");
> > > + goto out_complete;
> > > + }
> >
> > See my comment above for a bog standard i2c_read. Aren't you
> > getting
> > the completion for the address before the read is even started ?
>
> In practice no, but it is probably best to be safe :-)
Yup :)
> >
> > > + status_ack |= ASPEED_I2CD_INTR_RX_DONE;
> > > +
> > > + recv_byte = aspeed_i2c_read(bus,
> > > ASPEED_I2C_BYTE_BUF_REG) >> 8;
> > > + msg->buf[bus->buf_index++] = recv_byte;
> > > +
> > > + if (msg->flags & I2C_M_RECV_LEN &&
> > > + recv_byte <= I2C_SMBUS_BLOCK_MAX) {
> > > + msg->len = recv_byte +
> > > + ((msg->flags &
> > > I2C_CLIENT_PEC) ? 2 : 1);
>
> ...
> > > + return ((clk_high << ASPEED_I2CD_TIME_SCL_HIGH_SHIFT)
> > > + & ASPEED_I2CD_TIME_SCL_HIGH_MASK)
> > > + | ((clk_low <<
> > > ASPEED_I2CD_TIME_SCL_LOW_SHIFT)
> > > + & ASPEED_I2CD_TIME_SCL_LOW_MASK)
> > > + | (base_clk &
> > > ASPEED_I2CD_TIME_BASE_DIVISOR_MASK);
> > > +}
> >
> > As I think I mentioned earlier, the AST2500 has a slightly
> > different
> > register layout which support larger values for high and low, thus
> > allowing a finer granularity.
>
> I am developing against the 2500.
Yes but we'd like the driver to work with both :-)
> > BTW. In case you haven't, I would suggest you copy/paste the above
> > in
> > a userspace app and run it for all frequency divisors and see if
> > your
> > results match the aspeed table :)
>
> Good call.
If you end up doing that, can you shoot it my way ? I can take care
of making sure it's all good for the 2400.
> > > +static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus,
> > > + struct platform_device *pdev)
> > > +{
> > > + u32 clk_freq, divisor;
> > > + struct clk *pclk;
> > > + int ret;
> > > +
> > > + pclk = devm_clk_get(&pdev->dev, NULL);
> > > + if (IS_ERR(pclk)) {
> > > + dev_err(&pdev->dev, "clk_get failed\n");
> > > + return PTR_ERR(pclk);
> > > + }
> > > + ret = of_property_read_u32(pdev->dev.of_node,
> > > + "clock-frequency", &clk_freq);
> >
> > See my previous comment about calling that 'bus-frequency' rather
> > than 'clock-frequency'.
> >
> > > + if (ret < 0) {
> > > + dev_err(&pdev->dev,
> > > + "Could not read clock-frequency
> > > property\n");
> > > + clk_freq = 100000;
> > > + }
> > > + divisor = clk_get_rate(pclk) / clk_freq;
> > > + /* We just need the clock rate, we don't actually use the
> > > clk object. */
> > > + devm_clk_put(&pdev->dev, pclk);
> > > +
> > > + /* Set AC Timing */
> > > + if (clk_freq / 1000 > 1000) {
> > > + aspeed_i2c_write(bus, aspeed_i2c_read(bus,
> > > + ASPEED_I2C_FU
> > > N_CTRL_REG) |
> > > + ASPEED_I2CD_M_HIGH_SPEED_EN |
> > > + ASPEED_I2CD_M_SDA_DRIVE_1T_EN |
> > > + ASPEED_I2CD_SDA_DRIVE_1T_EN,
> > > + ASPEED_I2C_FUN_CTRL_REG);
> > > +
> > > + aspeed_i2c_write(bus, 0x3,
> > > ASPEED_I2C_AC_TIMING_REG2);
> > > + aspeed_i2c_write(bus,
> > > aspeed_i2c_get_clk_reg_val(divisor),
> > > + ASPEED_I2C_AC_TIMING_REG1);
> >
> > I already discussed by doubts about the above. I can try to scope
> > it with the EVB if you don't get to it. For now I'd rather take the
> > code out.
> >
> > We should ask aspeed from what frequency the "1T" stuff is useful.
>
> Will do, I will try to rope Ryan in on the next review; it will be
> good for him to get used to working with upstream anyway.
Yup. However, for the sake of getting something upstream (and in
OpenBMC 4.10 kernel) asap, I would suggest just dropping support
for those fast speeds for now, we can add them back later.
> >
> > > + } else {
> > > + aspeed_i2c_write(bus,
> > > aspeed_i2c_get_clk_reg_val(divisor),
> > > + ASPEED_I2C_AC_TIMING_REG1);
> > > + aspeed_i2c_write(bus, ASPEED_NO_TIMEOUT_CTRL,
> > > + ASPEED_I2C_AC_TIMING_REG2);
> > > + }
>
> ...
> > > + spin_lock_init(&bus->lock);
> > > + init_completion(&bus->cmd_complete);
> > > + bus->adap.owner = THIS_MODULE;
> > > + bus->adap.retries = 0;
> > > + bus->adap.timeout = 5 * HZ;
> > > + bus->adap.algo = &aspeed_i2c_algo;
> > > + bus->adap.algo_data = bus;
> > > + bus->adap.dev.parent = &pdev->dev;
> > > + bus->adap.dev.of_node = pdev->dev.of_node;
> > > + snprintf(bus->adap.name, sizeof(bus->adap.name), "Aspeed
> > > i2c");
> >
> > Another trivial one, should we put some kind of bus number
> > in that string ?
>
> Whoops, looks like I missed this one; I will get to it in the next
> revision.
Ok. I noticed you missed that in v7, so I assume you mean v8 :-)
> >
> > > + bus->dev = &pdev->dev;
> > > +
> > > + /* reset device: disable master & slave functions */
> > > + aspeed_i2c_write(bus, 0, ASPEED_I2C_FUN_CTRL_REG);
>
> ...
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree"
> in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v4 07/10] mfd: axp20x: add axp20x-regulator cell for AXP803
From: Chen-Yu Tsai @ 2017-04-25 2:17 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Thomas Gleixner, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
Lee Jones, Liam Girdwood, linux-kernel, devicetree,
linux-arm-kernel, linux-sunxi
In-Reply-To: <20170424160103.9447-8-icenowy-h8G6r0blFSE@public.gmane.org>
On Tue, Apr 25, 2017 at 12:01 AM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> wrote:
> As axp20x-regulator now supports AXP803, add a cell for it.
>
> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> ---
> Changes in v4:
> - Added a trailing comma for new cell, for easier further cell addition.
> Changes in v3:
> - Make the new cell one-liner.
>
> drivers/mfd/axp20x.c | 3 ++-
> drivers/regulator/axp20x-regulator.c | 6 +++---
Squashed in wrong patch?
ChenYu
^ permalink raw reply
* Re: Re: [PATCH 1/2] PCI: mediatek: Add Mediatek PCIe host controller support
From: Ryder Lee @ 2017-04-25 2:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Arnd Bergmann,
linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Bjorn Helgaas,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170424220218.GA18659-1RhO1Y9PlrlHTL0Zs8A6p5iNqAH0jzoTYJqu5kTmcBRl57MIdRCFDg@public.gmane.org>
Hi,
On Mon, 2017-04-24 at 17:02 -0500, Bjorn Helgaas wrote:
> Hi Ryder,
>
> Looks good, but I have a few questions below.
>
> On Sun, Apr 23, 2017 at 04:19:02PM +0800, Ryder Lee wrote:
> > Add support for the Mediatek PCIe controller which can be found
> > on MT7623A/N, MT2701 and MT8521p platforms.
> >
> > Signed-off-by: Ryder Lee <ryder.lee-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > ---
> > drivers/pci/host/Kconfig | 11 +
> > drivers/pci/host/Makefile | 1 +
> > drivers/pci/host/pcie-mediatek.c | 611 +++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 623 insertions(+)
> > create mode 100644 drivers/pci/host/pcie-mediatek.c
> >
> > diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> > index f7c1d4d..cf13b5d 100644
> > --- a/drivers/pci/host/Kconfig
> > +++ b/drivers/pci/host/Kconfig
> > @@ -174,6 +174,17 @@ config PCIE_ROCKCHIP
> > There is 1 internal PCIe port available to support GEN2 with
> > 4 slots.
> >
> > +config PCIE_MEDIATEK
> > + bool "Mediatek PCIe Controller for MT7623 SoCs families"
> > + depends on (ARM && ARCH_MEDIATEK) || COMPILE_TEST
> > + depends on OF
> > + depends on PCI
> > + select PCIEPORTBUS
> > + help
> > + Say Y here if you want to enable PCIe controller support on MT7623 A/N
> > + series SoCs. There is a one root complex with 3 root ports available.
> > + Each port supports Gen2 lane x1.
> > +
> > config VMD
> > depends on PCI_MSI && X86_64 && SRCU
> > tristate "Intel Volume Management Device Driver"
> > diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> > index 4d36866..265adff 100644
> > --- a/drivers/pci/host/Makefile
> > +++ b/drivers/pci/host/Makefile
> > @@ -17,6 +17,7 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
> > obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
> > obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
> > obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
> > +obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
> > obj-$(CONFIG_VMD) += vmd.o
> >
> > # The following drivers are for devices that use the generic ACPI
> > diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
> > new file mode 100644
> > index 0000000..98e84d9
> > --- /dev/null
> > +++ b/drivers/pci/host/pcie-mediatek.c
> > @@ -0,0 +1,611 @@
> > +/*
> > + * PCIe host controller driver for Mediatek MT7623 SoCs families
> > + *
> > + * Copyright (c) 2017 MediaTek Inc.
> > + * Author: Ryder Lee <ryder.lee-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_pci.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/pci.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/reset.h>
> > +
> > +/* PCIe shared registers */
> > +#define PCIE_SYS_CFG 0x00
> > +#define PCIE_INT_ENABLE 0x0c
> > +#define PCIE_CFG_ADDR 0x20
> > +#define PCIE_CFG_DATA 0x24
> > +
> > +/* PCIe per port registers */
> > +#define PCIE_BAR0_SETUP 0x10
> > +#define PCIE_BAR1_SETUP 0x14
> > +#define PCIE_BAR0_MEM_BASE 0x18
> > +#define PCIE_CLASS 0x34
> > +#define PCIE_LINK_STATUS 0x50
> > +
> > +#define PCIE_PORT_INT_EN(x) BIT(20 + (x))
> > +#define PCIE_PORT_PERST(x) BIT(1 + (x))
> > +#define PCIE_PORT_LINKUP BIT(0)
> > +#define PCIE_BAR_MAP_MAX GENMASK(31, 16)
> > +
> > +#define PCIE_BAR_ENABLE BIT(0)
> > +#define PCIE_REVISION_ID BIT(0)
> > +#define PCIE_CLASS_CODE (0x60400 << 8)
> > +#define PCIE_CONF_REG(regn) (((regn) & GENMASK(7, 2)) | \
> > + ((((regn) >> 8) & GENMASK(3, 0)) << 24))
> > +#define PCIE_CONF_FUN(fun) (((fun) << 8) & GENMASK(10, 8))
> > +#define PCIE_CONF_DEV(dev) (((dev) << 11) & GENMASK(15, 11))
> > +#define PCIE_CONF_BUS(bus) (((bus) << 16) & GENMASK(23, 16))
> > +#define PCIE_CONF_ADDR(regn, fun, dev, bus) \
> > + (PCIE_CONF_REG(regn) | PCIE_CONF_FUN(fun) | \
> > + PCIE_CONF_DEV(dev) | PCIE_CONF_BUS(bus))
> > +
> > +/* Mediatek specific configuration registers */
> > +#define PCIE_FTS_NUM 0x70c
> > +#define PCIE_FTS_NUM_MASK GENMASK(15, 8)
> > +#define PCIE_FTS_NUM_L0(x) ((x) & 0xff << 8)
> > +
> > +#define PCIE_FC_CREDIT 0x73c
> > +#define PCIE_FC_CREDIT_MASK (GENMASK(31, 31) | GENMASK(28, 16))
> > +#define PCIE_FC_CREDIT_VAL(x) ((x) << 16)
> > +
> > +/**
> > + * struct mtk_pcie_port - PCIe port information
> > + * @dev: pointer to root port device
> > + * @base: IO mapped register base
> > + * @list: port list
> > + * @pcie: pointer to PCIe host info
> > + * @reset: pointer to RC reset control
> > + * @regs: port memory region
> > + * @sys_ck: root port clock
> > + * @phy: pointer to phy control block
> > + * @irq: IRQ number
> > + * @lane: lane count
> > + * @index: port index
> > + */
> > +struct mtk_pcie_port {
> > + struct device *dev;
> > + void __iomem *base;
> > + struct list_head list;
> > + struct mtk_pcie *pcie;
> > + struct reset_control *reset;
> > + struct resource regs;
> > + struct clk *sys_ck;
> > + struct phy *phy;
> > + int irq;
> > + u32 lane;
> > + u32 index;
> > +};
> > +
> > +/**
> > + * struct mtk_pcie - PCIe host information
> > + * @dev: pointer to PCIe device
> > + * @base: IO mapped register Base
> > + * @free_ck: free-run reference clock
> > + * @resources: bus resources
> > + * @ports: pointer to PCIe port information
> > + */
> > +struct mtk_pcie {
> > + struct device *dev;
> > + void __iomem *base;
> > + struct clk *free_ck;
> > + struct list_head resources;
> > + struct list_head ports;
> > +};
> > +
> > +static inline bool mtk_pcie_link_is_up(struct mtk_pcie_port *port)
> > +{
> > + return !!(readl_relaxed(port->base + PCIE_LINK_STATUS) &
> > + PCIE_PORT_LINKUP);
> > +}
> > +
> > +static bool mtk_pcie_valid_device(struct mtk_pcie *pcie,
> > + struct pci_bus *bus, int devfn)
> > +{
> > + struct mtk_pcie_port *port;
> > + struct pci_dev *dev;
> > + struct pci_bus *pbus;
> > +
> > + /* if there is no link, then there is no device */
> > + list_for_each_entry(port, &pcie->ports, list) {
> > + if (bus->number == 0 && port->index == PCI_SLOT(devfn) &&
> > + mtk_pcie_link_is_up(port)) {
> > + return true;
> > + } else if (bus->number != 0) {
> > + pbus = bus;
> > + do {
> > + dev = pbus->self;
> > + if (port->index == PCI_SLOT(dev->devfn) &&
> > + mtk_pcie_link_is_up(port)) {
> > + return true;
> > + }
> > + pbus = dev->bus;
> > + } while (dev->bus->number != 0);
> > + }
> > + }
> > +
> > + return false;
> > +}
> > +
> > +static void mtk_pcie_port_free(struct mtk_pcie_port *port)
> > +{
> > + struct mtk_pcie *pcie = port->pcie;
> > + struct device *dev = pcie->dev;
> > +
> > + devm_iounmap(dev, port->base);
> > + devm_release_mem_region(dev, port->regs.start,
> > + resource_size(&port->regs));
> > + list_del(&port->list);
> > + devm_kfree(dev, port);
> > +}
> > +
> > +static int mtk_pcie_hw_rd_cfg(struct mtk_pcie *pcie, u32 bus, u32 devfn,
> > + int where, int size, u32 *val)
> > +{
> > + writel(PCIE_CONF_ADDR(where, PCI_FUNC(devfn), PCI_SLOT(devfn), bus),
> > + pcie->base + PCIE_CFG_ADDR);
> > +
> > + *val = 0;
> > +
> > + switch (size) {
> > + case 1:
> > + *val = readb(pcie->base + PCIE_CFG_DATA + (where & 3));
> > + break;
> > + case 2:
> > + *val = readw(pcie->base + PCIE_CFG_DATA + (where & 2));
> > + break;
> > + case 4:
> > + *val = readl(pcie->base + PCIE_CFG_DATA);
> > + break;
> > + }
> > +
> > + return PCIBIOS_SUCCESSFUL;
> > +}
> > +
> > +static int mtk_pcie_hw_wr_cfg(struct mtk_pcie *pcie, u32 bus, u32 devfn,
> > + int where, int size, u32 val)
> > +
> > +{
> > + writel(PCIE_CONF_ADDR(where, PCI_FUNC(devfn), PCI_SLOT(devfn), bus),
> > + pcie->base + PCIE_CFG_ADDR);
> > +
> > + switch (size) {
> > + case 1:
> > + writeb(val, pcie->base + PCIE_CFG_DATA + (where & 3));
> > + break;
> > + case 2:
> > + writew(val, pcie->base + PCIE_CFG_DATA + (where & 2));
> > + break;
> > + case 4:
> > + writel(val, pcie->base + PCIE_CFG_DATA);
> > + break;
> > + }
> > +
> > + return PCIBIOS_SUCCESSFUL;
> > +}
> > +
> > +static int mtk_pcie_read_config(struct pci_bus *bus, u32 devfn,
> > + int where, int size, u32 *val)
> > +{
> > + struct mtk_pcie *pcie = bus->sysdata;
> > + u32 bn = bus->number;
> > +
> > + if (!mtk_pcie_valid_device(pcie, bus, devfn)) {
> > + *val = 0xffffffff;
> > + return PCIBIOS_DEVICE_NOT_FOUND;
> > + }
>
> I know there are some other drivers with the *_valid_device() pattern
> in their config accessors, but I don't like it because it's racy.
> It's possible for the link to be up for the test above, then go down
> before the actual config access below.
>
> Your hardware *should* do something sensible if we try to read config
> space when the link is down, and ideally that would be enough that we
> don't need this "valid_device()" check.
>
Yup,it's unnecessary, will remove it.
> > + return mtk_pcie_hw_rd_cfg(pcie, bn, devfn, where, size, val);
> > +}
> > +
> > +static int mtk_pcie_write_config(struct pci_bus *bus, u32 devfn,
> > + int where, int size, u32 val)
> > +{
> > + struct mtk_pcie *pcie = bus->sysdata;
> > + u32 bn = bus->number;
> > +
> > + if (!mtk_pcie_valid_device(pcie, bus, devfn))
> > + return PCIBIOS_DEVICE_NOT_FOUND;
> > +
> > + return mtk_pcie_hw_wr_cfg(pcie, bn, devfn, where, size, val);
> > +}
> > +
> > +static struct pci_ops mtk_pcie_ops = {
> > + .read = mtk_pcie_read_config,
> > + .write = mtk_pcie_write_config,
> > +};
> > +
> > +static void mtk_pcie_configure_rc(struct mtk_pcie_port *port)
> > +{
> > + struct mtk_pcie *pcie = port->pcie;
> > + u32 val;
> > +
> > + /* enable interrupt */
> > + val = readl(pcie->base + PCIE_INT_ENABLE);
> > + val |= PCIE_PORT_INT_EN(port->index);
> > + writel(val, pcie->base + PCIE_INT_ENABLE);
> > +
> > + /* map to all DDR region. We need to set it before cfg operation. */
> > + writel(PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE,
> > + port->base + PCIE_BAR0_SETUP);
> > +
> > + /* configure class Code and revision ID */
> > + writel(PCIE_CLASS_CODE | PCIE_REVISION_ID,
> > + port->base + PCIE_CLASS);
> > +
> > + /* configure FC credit */
> > + mtk_pcie_hw_rd_cfg(pcie, 0, (port->index << 3),
> > + PCIE_FC_CREDIT, 4, &val);
> > + val &= ~PCIE_FC_CREDIT_MASK;
> > + val |= PCIE_FC_CREDIT_VAL(0x806c);
> > + mtk_pcie_hw_wr_cfg(pcie, 0, (port->index << 3),
> > + PCIE_FC_CREDIT, 4, val);
> > +
> > + /* configure RC FTS number to 250 when it leaves L0s */
> > + mtk_pcie_hw_rd_cfg(pcie, 0, (port->index << 3),
> > + PCIE_FTS_NUM, 4, &val);
> > + val &= ~PCIE_FTS_NUM_MASK;
> > + val |= PCIE_FTS_NUM_L0(0x50);
> > + mtk_pcie_hw_wr_cfg(pcie, 0, (port->index << 3),
> > + PCIE_FTS_NUM, 4, val);
> > +}
> > +
> > +static void mtk_pcie_assert_ports(struct mtk_pcie_port *port)
> > +{
> > + struct mtk_pcie *pcie = port->pcie;
> > + u32 val;
> > +
> > + /* assert port PERST_N */
> > + val = readl(pcie->base + PCIE_SYS_CFG);
> > + val |= PCIE_PORT_PERST(port->index);
> > + writel(val, pcie->base + PCIE_SYS_CFG);
> > +
> > + /* de-assert port PERST_N */
> > + val = readl(pcie->base + PCIE_SYS_CFG);
> > + val &= ~PCIE_PORT_PERST(port->index);
> > + writel(val, pcie->base + PCIE_SYS_CFG);
> > +
> > + /*
> > + * at least 100ms delay because PCIe v2.0 need more time to
> > + * train from Gen1 to Gen2
> > + */
> > + msleep(100);
> > +}
> > +
> > +static int mtk_pcie_enable_ports(struct mtk_pcie *pcie)
> > +{
> > + struct device *dev = pcie->dev;
> > + struct mtk_pcie_port *port, *tmp;
> > + int err, linkup = 0;
> > +
> > + list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> > + err = clk_prepare_enable(port->sys_ck);
> > + if (err) {
> > + dev_err(dev, "failed to enable port%d clock\n",
> > + port->index);
> > + continue;
> > + }
> > +
> > + /* assert RC */
> > + reset_control_assert(port->reset);
> > + /* de-assert RC */
> > + reset_control_deassert(port->reset);
> > +
> > + /* power on PHY */
> > + err = phy_power_on(port->phy);
> > + if (err) {
> > + dev_err(dev, "failed to power on port%d phy\n",
> > + port->index);
> > + goto err_phy_on;
> > + }
> > +
> > + mtk_pcie_assert_ports(port);
> > +
> > + /* if link up, then setup root port configuration space */
> > + if (mtk_pcie_link_is_up(port)) {
> > + mtk_pcie_configure_rc(port);
> > + linkup++;
> > + continue;
> > + }
> > +
> > + dev_info(dev, "Port%d link down\n", port->index);
> > +
> > + phy_power_off(port->phy);
> > +err_phy_on:
> > + clk_disable_unprepare(port->sys_ck);
> > + mtk_pcie_port_free(port);
> > + }
> > +
> > + return linkup;
> > +}
> > +
> > +static int mtk_pcie_get_port_resource(struct mtk_pcie_port *port,
> > + struct device_node *node)
> > +{
> > + struct device *dev = port->pcie->dev;
> > + struct platform_device *pdev = to_platform_device(dev);
> > + struct platform_device *plat_dev;
> > + char name[10];
> > + int err;
> > +
> > + err = of_address_to_resource(node, 0, &port->regs);
> > + if (err) {
> > + dev_err(dev, "failed to parse address: %d\n", err);
> > + return err;
> > + }
> > +
> > + port->base = devm_ioremap_resource(dev, &port->regs);
> > + if (IS_ERR(port->base)) {
> > + dev_err(dev, "failed to map port%d base\n", port->index);
> > + return PTR_ERR(port->base);
> > + }
> > +
> > + plat_dev = of_find_device_by_node(node);
> > + if (!plat_dev) {
> > + plat_dev = of_platform_device_create(
> > + node, NULL,
> > + platform_bus_type.dev_root);
> > + if (!plat_dev)
> > + return -EPROBE_DEFER;
> > + }
> > +
> > + port->dev = &plat_dev->dev;
> > +
> > + port->irq = platform_get_irq(pdev, port->index);
> > + if (!port->irq) {
> > + dev_err(dev, "failed to get irq\n");
> > + return -ENODEV;
> > + }
> > +
> > + port->sys_ck = devm_clk_get(port->dev, "sys_ck");
> > + if (IS_ERR(port->sys_ck)) {
> > + dev_err(port->dev, "failed to get port%d clock\n", port->index);
> > + return PTR_ERR(port->sys_ck);
> > + }
> > +
> > + port->reset = devm_reset_control_get(port->dev, "pcie-reset");
> > + if (IS_ERR(port->reset)) {
> > + dev_err(port->dev, "failed to get port%d reset control\n",
> > + port->index);
> > + return PTR_ERR(port->reset);
> > + }
> > +
> > + snprintf(name, sizeof(name), "pcie-phy%d", port->index);
> > + port->phy = devm_of_phy_get(port->dev, node, name);
> > + if (IS_ERR(port->phy)) {
> > + dev_err(port->dev, "failed to get port%d phy\n", port->index);
> > + return PTR_ERR(port->phy);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_pcie_parse_and_add_res(struct mtk_pcie *pcie)
> > +{
> > + struct device *dev = pcie->dev;
> > + struct platform_device *pdev = to_platform_device(dev);
> > + struct device_node *node = dev->of_node, *child;
> > + struct resource_entry *win, *tmp;
> > + struct resource *regs;
> > + resource_size_t iobase;
> > + int err;
> > +
> > + /* parse shared resources */
> > + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + pcie->base = devm_ioremap_resource(dev, regs);
> > + if (IS_ERR(pcie->base)) {
> > + dev_err(dev, "failed to get PCIe base\n");
> > + return PTR_ERR(pcie->base);
> > + }
> > +
> > + pcie->free_ck = devm_clk_get(dev, "free_ck");
> > + if (IS_ERR(pcie->free_ck)) {
> > + dev_err(dev, "failed to get free_ck\n");
> > + return PTR_ERR(pcie->free_ck);
> > + }
> > +
> > + err = of_pci_get_host_bridge_resources(node, 0, 0xff, &pcie->resources,
> > + &iobase);
> > + if (err)
> > + return err;
> > +
> > + err = devm_request_pci_bus_resources(dev, &pcie->resources);
> > + if (err)
> > + return err;
> > +
> > + resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
> > + struct resource *res = win->res;
> > +
> > + switch (resource_type(res)) {
> > + case IORESOURCE_IO:
> > + err = pci_remap_iospace(res, iobase);
> > + if (err) {
> > + dev_warn(dev, "failed to map resource %pR\n",
> > + res);
> > + resource_list_destroy_entry(win);
> > + }
> > + break;
> > + }
> > + }
> > +
> > + /* parse port resources */
> > + for_each_child_of_node(node, child) {
> > + struct mtk_pcie_port *port;
> > + int index;
> > +
> > + err = of_pci_get_devfn(child);
> > + if (err < 0) {
> > + dev_err(pcie->dev, "failed to parse devfn: %d\n", err);
>
> dev_err(dev, ...)
OK.
> > + return err;
> > + }
> > +
> > + index = PCI_SLOT(err);
> > + if (index < 1) {
> > + dev_err(dev, "invalid port number: %d\n", index);
> > + return -EINVAL;
> > + }
> > +
> > + index--;
> > +
> > + if (!of_device_is_available(child))
> > + continue;
> > +
> > + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> > + if (!port)
> > + return -ENOMEM;
> > +
> > + err = of_property_read_u32(child, "num-lanes", &port->lane);
> > + if (err) {
> > + dev_err(dev, "missing num-lanes property\n");
> > + return err;
> > + }
> > +
> > + port->index = index;
> > + port->pcie = pcie;
> > +
> > + err = mtk_pcie_get_port_resource(port, child);
> > + if (err)
> > + return err;
> > +
> > + INIT_LIST_HEAD(&port->list);
> > + list_add_tail(&port->list, &pcie->ports);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +/*
> > + * This IP lacks interrupt status register to check or map INTx from
> > + * different devices at the same time.
> > + */
> > +static int __init mtk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> > +{
> > + struct mtk_pcie *pcie = dev->bus->sysdata;
> > + struct mtk_pcie_port *port;
> > +
> > + list_for_each_entry(port, &pcie->ports, list)
> > + if (port->index == slot)
> > + return port->irq;
> > +
> > + return -1;
> > +}
> > +
> > +static int mtk_pcie_register_ports(struct mtk_pcie *pcie)
> > +{
> > + struct pci_bus *bus, *child;
> > +
> > + bus = pci_scan_root_bus(pcie->dev, 0, &mtk_pcie_ops, pcie,
> > + &pcie->resources);
> > + if (!bus) {
> > + dev_err(pcie->dev, "failed to create root bus\n");
> > + return -ENOMEM;
> > + }
> > +
> > + if (!pci_has_flag(PCI_PROBE_ONLY)) {
> > + pci_fixup_irqs(pci_common_swizzle, mtk_pcie_map_irq);
> > + pci_bus_size_bridges(bus);
> > + pci_bus_assign_resources(bus);
> > +
> > + list_for_each_entry(child, &bus->children, node)
> > + pcie_bus_configure_settings(child);
>
> Do you actually need the functionality of PCI_PROBE_ONLY? We're
> trying to get rid of this, so if you don't need it, please omit it.
>
> If you *do* need it, can you include a note about why?
>
> If you do need it, I don't think PCI_PROBE_ONLY should control
> pci_fixup_irqs() or pcie_bus_configure_settings(). I know there is
> some other similar code that does this, but I think PCI_PROBE_ONLY
> should only influence resource assignment, i.e., BARs and bridge
> windows. I don't want it to influence IRQs or the MPS/MRRS settings
> done by pcie_bus_configure_settings() if we can avoid it.
I will remove it, thanks.
> > + }
> > +
> > + pci_bus_add_devices(bus);
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_pcie_probe(struct platform_device *pdev)
> > +{
> > + struct mtk_pcie *pcie;
> > + int err;
> > +
> > + pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
> > + if (!pcie)
> > + return -ENOMEM;
> > +
> > + pcie->dev = &pdev->dev;
> > + platform_set_drvdata(pdev, pcie);
> > +
> > + /*
> > + * parse PCI ranges, configuration bus range and
> > + * request their resources
> > + */
> > + INIT_LIST_HEAD(&pcie->ports);
> > + INIT_LIST_HEAD(&pcie->resources);
> > +
> > + err = mtk_pcie_parse_and_add_res(pcie);
> > + if (err)
> > + goto err_parse;
> > +
> > + pm_runtime_enable(pcie->dev);
> > + err = pm_runtime_get_sync(pcie->dev);
> > + if (err)
> > + goto err_pm;
> > +
> > + err = clk_prepare_enable(pcie->free_ck);
> > + if (err) {
> > + dev_err(pcie->dev, "failed to enable free_ck\n");
> > + goto err_free_ck;
> > + }
> > +
> > + /* power on PCIe ports */
> > + err = mtk_pcie_enable_ports(pcie);
> > + if (!err)
> > + goto err_enable;
> > +
> > + /* register PCIe ports */
> > + err = mtk_pcie_register_ports(pcie);
> > + if (err)
> > + goto err_enable;
> > +
> > + return 0;
> > +
> > +err_enable:
> > + clk_disable_unprepare(pcie->free_ck);
> > +err_free_ck:
> > + pm_runtime_put_sync(pcie->dev);
> > +err_pm:
> > + pm_runtime_disable(pcie->dev);
> > +err_parse:
> > + pci_free_resource_list(&pcie->resources);
> > +
> > + return err;
> > +}
> > +
> > +static const struct of_device_id mtk_pcie_ids[] = {
> > + { .compatible = "mediatek,mt7623-pcie"},
> > + { .compatible = "mediatek,mt2701-pcie"},
> > + {},
> > +};
> > +MODULE_DEVICE_TABLE(of, mtk_pcie_ids);
> > +
> > +static struct platform_driver mtk_pcie_driver = {
> > + .probe = mtk_pcie_probe,
> > + .driver = {
> > + .name = "mtk-pcie",
> > + .of_match_table = mtk_pcie_ids,
>
> Per [1], I think you should have ".suppress_bind_attrs = true," here.
> Without it, apparently you can easily crash the system by unbinding
> the driver, as in [2].
>
> [1] https://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/commit/?id=65e0527b933a
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git/commit/?id=073d3dbe9a7c
OK!
> > + },
> > +};
> > +
> > +builtin_platform_driver(mtk_pcie_driver);
> > +
> > +MODULE_DESCRIPTION("Mediatek PCIe host driver for MT7623 SoCs families");
> > +MODULE_LICENSE("GPL v2");
> > --
> > 1.9.1
> >
Thanks for your review!
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCHv2 3/3] ARM: socfpga: drm driver updates in socfpga_defconfig
From: hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w @ 2017-04-25 2:06 UTC (permalink / raw)
To: daniel.vetter-ral2JQCrhuEAvxtiuMwx3w,
dinguyen-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: tien.hock.loh-ral2JQCrhuEAvxtiuMwx3w,
hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Ong-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493086006-4392-1-git-send-email-hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
From: "Ong, Hean Loong" <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Intel FPGA Video and Image Processing Suite Frame Buffer II
driver config for Arria 10 devkit and its variants
Signed-off-by: Ong, Hean Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
v2:
* Added drm frame bufferr II module support for Arria10
---
arch/arm/configs/socfpga_defconfig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
index 030264c..49ae269 100644
--- a/arch/arm/configs/socfpga_defconfig
+++ b/arch/arm/configs/socfpga_defconfig
@@ -110,6 +110,10 @@ CONFIG_MFD_ALTERA_A10SR=y
CONFIG_MFD_STMPE=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_DRM=m
+CONFIG_DRM_IVIP=m
+CONFIG_DRM_IVIP_OF=m
+CONFIG_FB=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC2=y
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCHv2 2/3] ARM: drm: Intel FPGA VIP Frame Buffer II drm driver
From: hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w @ 2017-04-25 2:06 UTC (permalink / raw)
To: daniel.vetter-ral2JQCrhuEAvxtiuMwx3w,
dinguyen-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: tien.hock.loh-ral2JQCrhuEAvxtiuMwx3w,
hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Ong-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493086006-4392-1-git-send-email-hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
From: "Ong, Hean Loong" <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Driver for Intel FPGA Video and Image Processing
Suite Frame Buffer II. The driver only supports the Intel
Arria10 devkit and its variants. This driver can be either
loaded staticlly or in modules. The OF device tree binding
is located at:
Documentation/devicetree/bindings/display/altr,vip-fb2.txt
Signed-off-by: Ong, Hean Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
v2:
* Simplify the driver by using drm_simple_display_pipe_init.
* Cleaned up some unused codes with no-ops
* Clean up Kconfig to use only DRM_IVIP
* Use DRM_GEM_CMA_FOPS for file operations
* Removed the use of fb_info to populate DT information
---
drivers/gpu/drm/Kconfig | 2 +
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/ivip/Kconfig | 13 +++
drivers/gpu/drm/ivip/Makefile | 9 ++
drivers/gpu/drm/ivip/intel_vip_conn.c | 96 +++++++++++++++++
drivers/gpu/drm/ivip/intel_vip_core.c | 171 +++++++++++++++++++++++++++++
drivers/gpu/drm/ivip/intel_vip_drv.h | 55 ++++++++++
drivers/gpu/drm/ivip/intel_vip_of.c | 195 ++++++++++++++++++++++++++++++++++
8 files changed, 542 insertions(+)
create mode 100644 drivers/gpu/drm/ivip/Kconfig
create mode 100644 drivers/gpu/drm/ivip/Makefile
create mode 100644 drivers/gpu/drm/ivip/intel_vip_conn.c
create mode 100644 drivers/gpu/drm/ivip/intel_vip_core.c
create mode 100644 drivers/gpu/drm/ivip/intel_vip_drv.h
create mode 100644 drivers/gpu/drm/ivip/intel_vip_of.c
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 78d7fc0..bc03c938 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -195,6 +195,8 @@ source "drivers/gpu/drm/nouveau/Kconfig"
source "drivers/gpu/drm/i915/Kconfig"
+source "drivers/gpu/drm/ivip/Kconfig"
+
config DRM_VGEM
tristate "Virtual GEM provider"
depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 59f0f9b..7cfe899 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_DRM_AMDGPU)+= amd/amdgpu/
obj-$(CONFIG_DRM_MGA) += mga/
obj-$(CONFIG_DRM_I810) += i810/
obj-$(CONFIG_DRM_I915) += i915/
+obj-$(CONFIG_DRM_IVIP) += ivip/
obj-$(CONFIG_DRM_MGAG200) += mgag200/
obj-$(CONFIG_DRM_VC4) += vc4/
obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
diff --git a/drivers/gpu/drm/ivip/Kconfig b/drivers/gpu/drm/ivip/Kconfig
new file mode 100644
index 0000000..9a8c5ce
--- /dev/null
+++ b/drivers/gpu/drm/ivip/Kconfig
@@ -0,0 +1,13 @@
+config DRM_IVIP
+ tristate "Intel FGPA Video and Image Processing"
+ depends on DRM && OF
+ select DRM_GEM_CMA_HELPER
+ select DRM_KMS_HELPER
+ select DRM_KMS_FB_HELPER
+ select DRM_KMS_CMA_HELPER
+ help
+ Choose this option if you have a Intel FPGA Arria 10 system
+ and above with a Display Port IP. This does not support legacy
+ Intel FPGA Cyclone V display port. Currently only single frame
+ buffer is supported. Note that ACPI and X_86 architecture is yet
+ to be supported.If M is selected the module would be called ivip.
diff --git a/drivers/gpu/drm/ivip/Makefile b/drivers/gpu/drm/ivip/Makefile
new file mode 100644
index 0000000..95291c6
--- /dev/null
+++ b/drivers/gpu/drm/ivip/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the drm device driver. This driver provides support for the
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+
+ccflags-y := -Iinclude/drm
+
+obj-$(CONFIG_DRM_IVIP) += ivip.o
+ivip-objs := intel_vip_of.o intel_vip_core.o \
+intel_vip_conn.o
diff --git a/drivers/gpu/drm/ivip/intel_vip_conn.c b/drivers/gpu/drm/ivip/intel_vip_conn.c
new file mode 100644
index 0000000..499d3b4
--- /dev/null
+++ b/drivers/gpu/drm/ivip/intel_vip_conn.c
@@ -0,0 +1,96 @@
+/*
+ * intel_vip_conn.c -- Intel Video and Image Processing(VIP)
+ * Frame Buffer II driver
+ *
+ * This driver supports the Intel VIP Frame Reader component.
+ * More info on the hardware can be found in the Intel Video
+ * and Image Processing Suite User Guide at this address
+ * http://www.altera.com/literature/ug/ug_vip.pdf.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * Authors:
+ * Ong, Hean-Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_encoder_slave.h>
+#include <drm/drm_plane_helper.h>
+
+static enum drm_connector_status
+intelvipfb_drm_connector_detect(struct drm_connector *connector, bool force)
+{
+ return connector_status_connected;
+}
+
+static void intelvipfb_drm_connector_destroy(struct drm_connector *connector)
+{
+ drm_connector_unregister(connector);
+ drm_connector_cleanup(connector);
+}
+
+static const struct drm_connector_funcs intelvipfb_drm_connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .reset = drm_atomic_helper_connector_reset,
+ .detect = intelvipfb_drm_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = intelvipfb_drm_connector_destroy,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int intelvipfb_drm_connector_get_modes(struct drm_connector *connector)
+{
+ struct drm_device *drm = connector->dev;
+ int count;
+
+ count = drm_add_modes_noedid(connector, drm->mode_config.max_width,
+ drm->mode_config.max_height);
+ drm_set_preferred_mode(connector, drm->mode_config.max_width,
+ drm->mode_config.max_height);
+ return count;
+}
+
+static const struct drm_connector_helper_funcs
+intelvipfb_drm_connector_helper_funcs = {
+ .get_modes = intelvipfb_drm_connector_get_modes,
+};
+
+struct drm_connector *
+intelvipfb_conn_setup(struct drm_device *drm)
+{
+ struct drm_connector *conn;
+ int ret;
+
+ conn = devm_kzalloc(drm->dev, sizeof(*conn), GFP_KERNEL);
+ if (IS_ERR(conn))
+ return NULL;
+
+ ret = drm_connector_init(drm, conn, &intelvipfb_drm_connector_funcs,
+ DRM_MODE_CONNECTOR_DisplayPort);
+ if (ret < 0) {
+ dev_err(drm->dev, "failed to initialize drm connector\n");
+ ret = -ENOMEM;
+ goto error_connector_cleanup;
+ }
+
+ drm_connector_helper_add(conn, &intelvipfb_drm_connector_helper_funcs);
+
+ return conn;
+
+error_connector_cleanup:
+ drm_connector_cleanup(conn);
+
+ return NULL;
+}
diff --git a/drivers/gpu/drm/ivip/intel_vip_core.c b/drivers/gpu/drm/ivip/intel_vip_core.c
new file mode 100644
index 0000000..4e83343
--- /dev/null
+++ b/drivers/gpu/drm/ivip/intel_vip_core.c
@@ -0,0 +1,171 @@
+/*
+ * intel_vip_core.c -- Intel Video and Image Processing(VIP)
+ * Frame Buffer II driver
+ *
+ * This driver supports the Intel VIP Frame Reader component.
+ * More info on the hardware can be found in the Intel Video
+ * and Image Processing Suite User Guide at this address
+ * http://www.altera.com/literature/ug/ug_vip.pdf.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * Authors:
+ * Ong, Hean-Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+
+#include "intel_vip_drv.h"
+
+static const u32 fbpriv_formats[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB565
+};
+
+static void intelvipfb_start_hw(void __iomem *base, resource_size_t addr)
+{
+ /*
+ * The frameinfo variable has to correspond to the size of the VIP Suite
+ * Frame Reader register 7 which will determine the maximum size used
+ * in this frameinfo
+ */
+
+ u32 frameinfo;
+
+ frameinfo =
+ readl(base + INTELVIPFB_FRAME_READER) & 0x00ffffff;
+ writel(frameinfo, base + INTELVIPFB_FRAME_INFO);
+ writel(addr, base + INTELVIPFB_FRAME_START);
+ /* Finally set the control register to 1 to start streaming */
+ writel(1, base + INTELVIPFB_CONTROL);
+}
+
+static void intelvipfb_disable_hw(void __iomem *base)
+{
+ /* set the control register to 0 to stop streaming */
+ writel(0, base + INTELVIPFB_CONTROL);
+}
+
+static const struct drm_mode_config_funcs intelvipfb_mode_config_funcs = {
+ .fb_create = drm_fb_cma_create,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
+};
+
+static struct drm_mode_config_helper_funcs intelvipfb_mode_config_helpers = {
+ .atomic_commit_tail = drm_atomic_helper_commit_tail,
+};
+
+static void intelvipfb_setup_mode_config(struct drm_device *drm)
+{
+ drm_mode_config_init(drm);
+ drm->mode_config.funcs = &intelvipfb_mode_config_funcs;
+ drm->mode_config.helper_private = &intelvipfb_mode_config_helpers;
+}
+
+static int intelvipfb_pipe_prepare_fb(struct drm_simple_display_pipe *pipe,
+ struct drm_plane_state *plane_state)
+{
+ return drm_fb_cma_prepare_fb(&pipe->plane, plane_state);
+}
+
+static struct drm_simple_display_pipe_funcs fbpriv_funcs = {
+ .prepare_fb = intelvipfb_pipe_prepare_fb,
+};
+
+int intelvipfb_probe(struct device *dev, void __iomem *base)
+{
+ int retval;
+ struct drm_device *drm;
+ struct intelvipfb_priv *fbpriv = dev_get_drvdata(dev);
+ struct drm_connector *connector;
+
+ dev_set_drvdata(dev, fbpriv);
+
+ drm = fbpriv->drm;
+
+ intelvipfb_setup_mode_config(drm);
+
+ connector = intelvipfb_conn_setup(drm);
+ if (!connector) {
+ dev_err(drm->dev, "Connector setup failed\n");
+ goto err_mode_config;
+ }
+
+ retval = drm_simple_display_pipe_init(drm, &fbpriv->pipe,
+ &fbpriv_funcs,
+ fbpriv_formats,
+ ARRAY_SIZE(fbpriv_formats),
+ connector);
+ if (retval < 0) {
+ dev_err(drm->dev, "Cannot setup simple display pipe\n");
+ goto err_mode_config;
+ }
+
+ fbpriv->fbcma = drm_fbdev_cma_init(drm, PREF_BPP,
+ drm->mode_config.num_connector);
+ if (!fbpriv->fbcma) {
+ fbpriv->fbcma = NULL;
+ dev_err(drm->dev, "Failed to init FB CMA area\n");
+ goto err_mode_config;
+ }
+
+ drm_mode_config_reset(drm);
+
+ intelvipfb_start_hw(base, drm->mode_config.fb_base);
+
+ drm_dev_register(drm, 0);
+
+ return retval;
+
+err_mode_config:
+
+ drm_mode_config_cleanup(drm);
+ return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(intelvipfb_probe);
+
+int intelvipfb_remove(struct device *dev)
+{
+ struct intelvipfb_priv *fbpriv = dev_get_drvdata(dev);
+ struct drm_device *drm = fbpriv->drm;
+
+ drm_dev_unregister(drm);
+
+ if (fbpriv->fbcma)
+ drm_fbdev_cma_fini(fbpriv->fbcma);
+
+ intelvipfb_disable_hw(fbpriv->base);
+ drm_mode_config_cleanup(drm);
+
+ drm_dev_unref(drm);
+
+ devm_kfree(dev, fbpriv);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(intelvipfb_remove);
+
+MODULE_AUTHOR("Ong, Hean-Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>");
+MODULE_DESCRIPTION("Intel VIP Frame Buffer II driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/ivip/intel_vip_drv.h b/drivers/gpu/drm/ivip/intel_vip_drv.h
new file mode 100644
index 0000000..8ef83f59
--- /dev/null
+++ b/drivers/gpu/drm/ivip/intel_vip_drv.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 Intel Corporation.
+ *
+ * Intel Video and Image Processing(VIP) Frame Buffer II driver.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ong, Hean-Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
+ *
+ */
+#ifndef _INTEL_VIP_DRV_H
+#define _INTEL_VIP_DRV_H
+#include <linux/io.h>
+#include <linux/fb.h>
+
+#define DRIVER_NAME "intelvipfb"
+#define BYTES_PER_PIXEL 4
+#define PREF_BPP 32
+#define CRTC_NUM 1
+#define CONN_NUM 1
+
+/* control registers */
+#define INTELVIPFB_CONTROL 0
+#define INTELVIPFB_STATUS 0x4
+#define INTELVIPFB_INTERRUPT 0x8
+#define INTELVIPFB_FRAME_COUNTER 0xC
+#define INTELVIPFB_FRAME_DROP 0x10
+#define INTELVIPFB_FRAME_INFO 0x14
+#define INTELVIPFB_FRAME_START 0x18
+#define INTELVIPFB_FRAME_READER 0x1C
+
+int intelvipfb_probe(struct device *dev, void __iomem *base);
+int intelvipfb_remove(struct device *dev);
+int intelvipfb_setup_crtc(struct drm_device *drm);
+struct drm_connector *intelvipfb_conn_setup(struct drm_device *drm);
+
+struct intelvipfb_priv {
+ struct drm_simple_display_pipe pipe;
+ struct drm_fbdev_cma *fbcma;
+ struct drm_device *drm;
+ void __iomem *base;
+};
+
+#endif
diff --git a/drivers/gpu/drm/ivip/intel_vip_of.c b/drivers/gpu/drm/ivip/intel_vip_of.c
new file mode 100644
index 0000000..7e3dc39
--- /dev/null
+++ b/drivers/gpu/drm/ivip/intel_vip_of.c
@@ -0,0 +1,195 @@
+/*
+ * intel_vip_of.c -- Intel Video and Image Processing(VIP)
+ * Frame Buffer II driver
+ *
+ * This driver supports the Intel VIP Frame Reader component.
+ * More info on the hardware can be found in the Intel Video
+ * and Image Processing Suite User Guide at this address
+ * http://www.altera.com/literature/ug/ug_vip.pdf.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * Authors:
+ * Ong, Hean-Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
+ *
+ */
+
+#include <linux/component.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_of.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+
+#include "intel_vip_drv.h"
+
+DEFINE_DRM_GEM_CMA_FOPS(fops);
+
+static struct drm_driver intelvipfb_drm = {
+ .driver_features =
+ DRIVER_GEM | DRIVER_PRIME |
+ DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC,
+ .gem_free_object_unlocked = drm_gem_cma_free_object,
+ .gem_vm_ops = &drm_gem_cma_vm_ops,
+ .dumb_create = drm_gem_cma_dumb_create,
+ .dumb_map_offset = drm_gem_cma_dumb_map_offset,
+ .dumb_destroy = drm_gem_dumb_destroy,
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_export = drm_gem_prime_export,
+ .gem_prime_import = drm_gem_prime_import,
+ .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
+ .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+ .gem_prime_vmap = drm_gem_cma_prime_vmap,
+ .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
+ .gem_prime_mmap = drm_gem_cma_prime_mmap,
+ .name = DRIVER_NAME,
+ .date = "20170329",
+ .desc = "Intel FPGA VIP SUITE",
+ .major = 1,
+ .minor = 0,
+ .patchlevel = 0,
+ .fops = &fops,
+};
+
+/*
+ * Setting up information derived from OF Device Tree Nodes
+ * max-width, max-height, bits per pixel, memory port width
+ */
+
+static int intelvipfb_drm_setup(struct device *dev,
+ struct intelvipfb_priv *fbpriv)
+{
+ struct drm_device *drm = fbpriv->drm;
+ struct device_node *np = dev->of_node;
+ int mem_word_width;
+ int max_h, max_w;
+ int bpp;
+ int ret;
+
+ ret = of_property_read_u32(np, "altr,max-width", &max_w);
+ if (ret) {
+ dev_err(dev,
+ "Missing required parameter 'altr,max-width'");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "altr,max-height", &max_h);
+ if (ret) {
+ dev_err(dev,
+ "Missing required parameter 'altr,max-height'");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "altr,bits-per-symbol", &bpp);
+ if (ret) {
+ dev_err(dev,
+ "Missing required parameter 'altr,bits-per-symbol'");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "altr,mem-port-width", &mem_word_width);
+ if (ret) {
+ dev_err(dev, "Missing required parameter 'altr,mem-port-width '");
+ return ret;
+ }
+
+ if (!(mem_word_width >= 32 && mem_word_width % 32 == 0)) {
+ dev_err(dev,
+ "mem-word-width is set to %i. must be >= 32 and multiple of 32.",
+ mem_word_width);
+ return -ENODEV;
+ }
+
+ drm->mode_config.min_width = 640;
+ drm->mode_config.min_height = 480;
+ drm->mode_config.max_width = max_w;
+ drm->mode_config.max_height = max_h;
+ drm->mode_config.preferred_depth = bpp * BYTES_PER_PIXEL;
+
+ return 0;
+}
+
+static int intelvipfb_of_probe(struct platform_device *pdev)
+{
+ int retval;
+ struct resource *reg_res;
+ struct intelvipfb_priv *fbpriv;
+ struct device *dev = &pdev->dev;
+ struct drm_device *drm;
+
+ fbpriv = devm_kzalloc(dev, sizeof(*fbpriv), GFP_KERNEL);
+ if (!fbpriv)
+ return -ENOMEM;
+
+ /*setup DRM */
+ drm = drm_dev_alloc(&intelvipfb_drm, dev);
+ if (IS_ERR(drm))
+ return PTR_ERR(drm);
+
+ retval = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32));
+ if (retval)
+ return -ENODEV;
+
+ fbpriv->drm = drm;
+
+ reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!reg_res)
+ return -ENOMEM;
+
+ fbpriv->base = devm_ioremap_resource(dev, reg_res);
+
+ if (IS_ERR(fbpriv->base)) {
+ dev_err(dev, "devm_ioremap_resource failed\n");
+ retval = PTR_ERR(fbpriv->base);
+ return -ENOMEM;
+ }
+
+ intelvipfb_drm_setup(dev, fbpriv);
+
+ dev_set_drvdata(dev, fbpriv);
+
+ return intelvipfb_probe(dev, fbpriv->base);
+}
+
+static int intelvipfb_of_remove(struct platform_device *pdev)
+{
+ return intelvipfb_remove(&pdev->dev);
+}
+
+/*
+ * The name vip-frame-buffer-2.0 is derived from
+ * http://www.altera.com/literature/ug/ug_vip.pdf
+ * frame buffer IP cores section 14
+ */
+
+static const struct of_device_id intelvipfb_of_match[] = {
+ { .compatible = "altr,vip-frame-buffer-2.0" },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, intelvipfb_of_match);
+
+static struct platform_driver intelvipfb_driver = {
+ .probe = intelvipfb_of_probe,
+ .remove = intelvipfb_of_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = intelvipfb_of_match,
+ },
+};
+
+module_platform_driver(intelvipfb_driver);
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCHv2 1/3] dt-bindings: display: Intel FPGA VIP drm driver Devicetree bindings
From: hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w @ 2017-04-25 2:06 UTC (permalink / raw)
To: daniel.vetter-ral2JQCrhuEAvxtiuMwx3w,
dinguyen-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: tien.hock.loh-ral2JQCrhuEAvxtiuMwx3w,
hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Ong-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493086006-4392-1-git-send-email-hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
From: "Ong, Hean Loong" <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Device tree binding for Intel FPGA Video and Image
Processing Suite. The binding involved would be generated
from the Altera (Intel) Qsys system. The bindings would
set the max width, max height, buts per pixel and memory
port width. The device tree binding only supports the Intel
Arria10 devkit and its variants. Vendor name retained as
altr.
Signed-off-by: Ong, Hean Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
v2:
* Moved Device Tree bindings to Documentation/devicetree/bindings/display/
* Added vendor name altr, to description
---
.../devicetree/bindings/display/altr,vip-fb2.txt | 30 ++++++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/altr,vip-fb2.txt
diff --git a/Documentation/devicetree/bindings/display/altr,vip-fb2.txt b/Documentation/devicetree/bindings/display/altr,vip-fb2.txt
new file mode 100644
index 0000000..bdffefb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/altr,vip-fb2.txt
@@ -0,0 +1,30 @@
+Intel Video and Image Processing(VIP) Frame Buffer II bindings
+
+Supported hardware: Arria 10 and above with display port IP
+
+The drm driver for the Arria 10 devkit would require the display resolution
+and pixel information to be included as these values are generated based
+on the FPGA design that drives the video connector attached to the drm driver
+Information the FPGA video IP component can be acquired from
+https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ug/ug_vip.pdf
+
+Required properties:
+
+- compatible: "altr,vip-frame-buffer-2.0"
+- reg: Physical base address and length of the framebuffer controller's
+ registers.
+- altr,max-width: The width of the framebuffer in pixels.
+- altr,max-height: The height of the framebuffer in pixels.
+- altr,bits-per-symbol: only "8" is currently supported
+- altr,mem-port-width = the bus width of the avalon master port on the frame reader
+
+Example:
+
+ dp_0_frame_buf: vip@100000280 {
+ compatible = "altr,vip-frame-buffer-2.0";
+ reg = <0x00000001 0x00000280 0x00000040>;
+ altr,max-width = <1280>;
+ altr,max-height = <720>;
+ altr,bits-per-symbol = <8>;
+ altr,mem-port-width = <128>;
+ };
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCHv2 0/3] Intel FPGA VIP Frame Buffer II DRM Driver
From: hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w @ 2017-04-25 2:06 UTC (permalink / raw)
To: daniel.vetter-ral2JQCrhuEAvxtiuMwx3w,
dinguyen-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: tien.hock.loh-ral2JQCrhuEAvxtiuMwx3w,
hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
From: Ong Hean Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Hi,
The new Intel Arria10 SOC FPGA devkit has a Display Port IP component
which requires a new driver. This is a virtual driver in which the
FGPA hardware would enable the Display Port based on the information
and data provided from the DRM frame buffer from the OS. Basically all
all information with reagrds to resolution and bits per pixel are
pre-configured on the FPGA design and these information are fed to
the driver via the device tree information as part of the hardware
information.
Further information can be obtained from
https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ug/ug_vip.pdf
Ong, Hean Loong (3):
dt-bindings: display: Intel FPGA VIP drm driver Devicetree bindings
ARM: drm: Intel FPGA VIP Frame Buffer II drm driver
ARM: socfpga: drm driver updates in socfpga_defconfig
.../devicetree/bindings/display/altr,vip-fb2.txt | 30 ++++
arch/arm/configs/socfpga_defconfig | 4 +
drivers/gpu/drm/Kconfig | 2 +
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/ivip/Kconfig | 13 ++
drivers/gpu/drm/ivip/Makefile | 9 +
drivers/gpu/drm/ivip/intel_vip_conn.c | 96 ++++++++++
drivers/gpu/drm/ivip/intel_vip_core.c | 171 ++++++++++++++++++
drivers/gpu/drm/ivip/intel_vip_drv.h | 55 ++++++
drivers/gpu/drm/ivip/intel_vip_of.c | 195 +++++++++++++++++++++
10 files changed, 576 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/altr,vip-fb2.txt
create mode 100644 drivers/gpu/drm/ivip/Kconfig
create mode 100644 drivers/gpu/drm/ivip/Makefile
create mode 100644 drivers/gpu/drm/ivip/intel_vip_conn.c
create mode 100644 drivers/gpu/drm/ivip/intel_vip_core.c
create mode 100644 drivers/gpu/drm/ivip/intel_vip_drv.h
create mode 100644 drivers/gpu/drm/ivip/intel_vip_of.c
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] arm64: dts: exynos: Remove the te-gpios property in the TM2 boards
From: Hoegeun Kwon @ 2017-04-25 1:54 UTC (permalink / raw)
To: robh+dt, mark.rutland, catalin.marinas, will.deacon, kgene, krzk
Cc: javier, devicetree, linux-arm-kernel, linux-samsung-soc,
linux-kernel, a.hajda, Hoegeun Kwon
In-Reply-To: <CGME20170425015437epcas5p43549d47e69519f43d89ba2de496ba451@epcas5p4.samsung.com>
The decon uses HW-TRIGGER, so TE interrupt is not necessary.
Therefore, remove the te-gpios property in the TM2 dts.
Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
---
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
index 3ff9527..23191eb 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -60,7 +60,6 @@
vci-supply = <&ldo28_reg>;
reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
- te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>;
};
};
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v3 1/3] mtd: nand: Cleanup/rework the atmel_nand driver
From: Brian Norris @ 2017-04-25 1:09 UTC (permalink / raw)
To: Boris Brezillon
Cc: Richard Weinberger, linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Nicolas Ferre, Alexandre Belloni, Haavard Skinnemoen,
Hans-Christian Egtvedt, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
Wenyou Yang, Josh Wu, David Woodhouse, Marek Vasut,
Cyrille Pitchen,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
devicetree-u79uwXL29TY76Z2rM5mHXA, Masahiro Yamada
In-Reply-To: <1489651362-17077-2-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On Thu, Mar 16, 2017 at 09:02:40AM +0100, Boris Brezillon wrote:
> diff --git a/drivers/mtd/nand/atmel/nand-controller.c b/drivers/mtd/nand/atmel/nand-controller.c
> new file mode 100644
> index 000000000000..f71b9e5d7d9d
> --- /dev/null
> +++ b/drivers/mtd/nand/atmel/nand-controller.c
> @@ -0,0 +1,2198 @@
[...]
> +static int
> +atmel_hsmc_nand_controller_legacy_init(struct atmel_hsmc_nand_controller *nc)
> +{
> + struct regmap_config regmap_conf = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
You assigned val_bits twice. Is that just a harmless mistake, or did you
mean to set something else?
(sparse and other tools complain about this)
> + };
Brian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 0/7] NFC: trf7970a: Fixups & convert to desc-based GPIO
From: Mark Greer @ 2017-04-25 0:19 UTC (permalink / raw)
To: Samuel Ortiz
Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw,
devicetree-u79uwXL29TY76Z2rM5mHXA, Mark Greer,
linux-wireless-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170120191745.29255-1-mgreer-luAo+O/VEmrlveNOaEYElw@public.gmane.org>
[-CC: Lauro Ramos Venancio <lauro.venancio-430g2QfJUUCGglJvpFV4uA@public.gmane.org> and
Aloisio Almeida Jr <aloisio.almeida-430g2QfJUUCGglJvpFV4uA@public.gmane.org>]
[+CC: linux-wireless]
On Fri, Jan 20, 2017 at 12:17:38PM -0700, Mark Greer wrote:
> These trf7970a driver patches do the following things:
> - a couple minor fixups
> - allow EN2 to not be managed by the driver (e.g., when its tied low by
> hardware
> - convert the driver to use the descriptor-based GPIO interface
> - remove support for 'vin-voltage-override' DT property
> - change the DTS example to indicate that EN and EN2 are active high GPIOs
> - add Mark Greer as the maintainer of the trf7970a driver
>
> Based on k.o. 44b4b46 (Merge tag 'armsoc-fixes' of
> git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc)
>
> v2->v3:
> - Removed "[PATCH v2 5/7] NFC: trf7970a: Clean up coding style issues"
> because it will make merging patches from Geoff Lansberry and others
> hard to apply. I will resubmit once those patches have been merged
> or rejected.
> - Added a patch to remove 'vin-voltage-override' DT property support as
> proper DT regulator set up makes it unnecessary.
>
> v1->v2:
> - Commit description fixups only; no functional changes.
>
> Mark Greer (7):
> NFC: trf7970a: Don't de-assert EN2 unless it was asserted
> NFC: trf7970a: Don't manage EN2 when not specified in DT
> NFC: trf7970a: Convert to descriptor based GPIO interface
> NFC: trf7970a: Remove useless comment
> NFC: trf7970a: Remove support for 'vin-voltage-override' DT property
> NFC: trf7970a: Enable pins are active high not active low
> MAINTAINERS: NFC: trf7970a: Add Mark Greer as maintainer
>
> .../devicetree/bindings/net/nfc/trf7970a.txt | 6 +-
> MAINTAINERS | 7 ++
> drivers/nfc/Kconfig | 2 +-
> drivers/nfc/trf7970a.c | 75 +++++++++-------------
> 4 files changed, 40 insertions(+), 50 deletions(-)
I've already mentioned this to Samuel privately but for everyone's sake,
I will respin this series because some patches that cause conflicts have
been accepted. I will also add some patches that I have made in the
interim. I apologize for the churn.
Mark
--
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: Add the ethernet and ethernet PHY to the cygnus core DT.
From: Eric Anholt @ 2017-04-25 0:02 UTC (permalink / raw)
To: Florian Fainelli, Vivien Didelot, Andrew Lunn,
netdev-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Ray Jui,
Scott Branden, Jon Mason
In-Reply-To: <1759fb29-0678-0ec5-5398-16c4a3ba9660-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 613 bytes --]
Florian Fainelli <f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> writes:
> On 04/24/2017 02:50 PM, Eric Anholt wrote:
>> Cygnus has a single amac controller connected to the B53 switch with 2
>> PHYs. On the BCM911360_EP platform, those two PHYs are connected to
>> the external ethernet jacks.
>>
>> Signed-off-by: Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
>
> This looks fine, just a few nits on the label names:
Thanks. I've applied all of these (and Andrew's and Scott's
suggestions), and I'll send out a new version once the DT maintainers
have had a chance to look.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: Add the ethernet and ethernet PHY to the cygnus core DT.
From: Eric Anholt @ 2017-04-25 0:00 UTC (permalink / raw)
To: Andrew Lunn
Cc: Florian Fainelli, Vivien Didelot, netdev, Rob Herring,
Mark Rutland, devicetree, linux-arm-kernel, linux-kernel,
bcm-kernel-feedback-list, Ray Jui, Scott Branden, Jon Mason
In-Reply-To: <20170424220842.GA26241@lunn.ch>
[-- Attachment #1: Type: text/plain, Size: 568 bytes --]
Andrew Lunn <andrew@lunn.ch> writes:
>> + mdio: mdio@18002000 {
>> + compatible = "brcm,iproc-mdio";
>> + reg = <0x18002000 0x8>;
>> + #size-cells = <1>;
>> + #address-cells = <0>;
>> +
>> + gphy0: eth-gphy@0 {
>> + reg = <0>;
>> + max-speed = <1000>;
>> + };
>> +
>> + gphy1: eth-gphy@1 {
>> + reg = <1>;
>> + max-speed = <1000>;
>> + };
>> + };
>
> Hi Eric
>
> Do these max-speed properties do anything useful? Is the PHY capable
> of > 1Gbps?
Not sure where I had those copy-and-pasted from, but they don't seem
necessary. Dropped.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply
* Re: [PATCH 1/2] net: dsa: b53: Add compatible strings for the Cygnus-family BCM11360.
From: Scott Branden @ 2017-04-24 23:57 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Vivien Didelot, Andrew Lunn,
netdev-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Ray Jui,
Scott Branden, Jon Mason
In-Reply-To: <8760hte4zw.fsf-omZaPlIz5HhaEpDpdNBo/KxOck334EZe@public.gmane.org>
On 17-04-24 04:54 PM, Eric Anholt wrote:
> Scott Branden <scott.branden-dY08KVG/lbpWk0Htik3J/w@public.gmane.org> writes:
>
>> Minor comment in line
>>
>> On 17-04-24 02:50 PM, Eric Anholt wrote:
>>> Cygnus is a small family of SoCs, of which we currently have
>>> devicetree for BCM11360 and BCM58300. The 11360's B53 is mostly the
>>> same as 58xx, just requiring a tiny bit of setup that was previously
>>> missing.
>>>
>>> Signed-off-by: Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
>>> ---
>>> Documentation/devicetree/bindings/net/dsa/b53.txt | 3 +++
>>> drivers/net/dsa/b53/b53_srab.c | 2 ++
>>> 2 files changed, 5 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/net/dsa/b53.txt b/Documentation/devicetree/bindings/net/dsa/b53.txt
>>> index d6c6e41648d4..49c93d3c0839 100644
>>> --- a/Documentation/devicetree/bindings/net/dsa/b53.txt
>>> +++ b/Documentation/devicetree/bindings/net/dsa/b53.txt
>>> @@ -29,6 +29,9 @@ Required properties:
>>> "brcm,bcm58625-srab"
>>> "brcm,bcm88312-srab" and the mandatory "brcm,nsp-srab string
>>>
>>> + For the BCM11360 SoC, must be:
>>> + "brcm,bcm11360-srab" and the mandatory "brcm,cygnus-srab string
>>> +
>> place in alphabetical order in the doc?
>
> Moved it above BCM5310x now. I hope that's what you meant.
>
Yes, sorry for not being more clear.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/2] net: dsa: b53: Add compatible strings for the Cygnus-family BCM11360.
From: Eric Anholt @ 2017-04-24 23:54 UTC (permalink / raw)
To: Scott Branden, Florian Fainelli, Vivien Didelot, Andrew Lunn,
netdev-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Ray Jui,
Scott Branden, Jon Mason
In-Reply-To: <a2f4f0c9-feea-291b-dae5-f4ed10f9c547-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1263 bytes --]
Scott Branden <scott.branden-dY08KVG/lbpWk0Htik3J/w@public.gmane.org> writes:
> Minor comment in line
>
> On 17-04-24 02:50 PM, Eric Anholt wrote:
>> Cygnus is a small family of SoCs, of which we currently have
>> devicetree for BCM11360 and BCM58300. The 11360's B53 is mostly the
>> same as 58xx, just requiring a tiny bit of setup that was previously
>> missing.
>>
>> Signed-off-by: Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
>> ---
>> Documentation/devicetree/bindings/net/dsa/b53.txt | 3 +++
>> drivers/net/dsa/b53/b53_srab.c | 2 ++
>> 2 files changed, 5 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/net/dsa/b53.txt b/Documentation/devicetree/bindings/net/dsa/b53.txt
>> index d6c6e41648d4..49c93d3c0839 100644
>> --- a/Documentation/devicetree/bindings/net/dsa/b53.txt
>> +++ b/Documentation/devicetree/bindings/net/dsa/b53.txt
>> @@ -29,6 +29,9 @@ Required properties:
>> "brcm,bcm58625-srab"
>> "brcm,bcm88312-srab" and the mandatory "brcm,nsp-srab string
>>
>> + For the BCM11360 SoC, must be:
>> + "brcm,bcm11360-srab" and the mandatory "brcm,cygnus-srab string
>> +
> place in alphabetical order in the doc?
Moved it above BCM5310x now. I hope that's what you meant.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply
* Re: [PATCH 1/2] net: dsa: b53: Add compatible strings for the Cygnus-family BCM11360.
From: Florian Fainelli @ 2017-04-24 23:17 UTC (permalink / raw)
To: Arun Parameswaran, Eric Anholt, Vivien Didelot, Andrew Lunn,
netdev-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Ray Jui,
Scott Branden, Jon Mason
In-Reply-To: <1361654c-e4eb-e0a0-3397-b43235b5ff60-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
On 04/24/2017 04:15 PM, Arun Parameswaran wrote:
>
>
> On 17-04-24 04:07 PM, Florian Fainelli wrote:
>> On 04/24/2017 04:03 PM, Arun Parameswaran wrote:
>>> Hi Eric
>>>
>>> A comment on the Device ID.
>>>
>>>
>>> On 17-04-24 02:50 PM, Eric Anholt wrote:
>>>> Cygnus is a small family of SoCs, of which we currently have
>>>> devicetree for BCM11360 and BCM58300. The 11360's B53 is mostly the
>>>> same as 58xx, just requiring a tiny bit of setup that was previously
>>>> missing.
>>>>
>>>> Signed-off-by: Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
>>>> ---
>>>> Documentation/devicetree/bindings/net/dsa/b53.txt | 3 +++
>>>> drivers/net/dsa/b53/b53_srab.c | 2 ++
>>>> 2 files changed, 5 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/net/dsa/b53.txt b/Documentation/devicetree/bindings/net/dsa/b53.txt
>>>> index d6c6e41648d4..49c93d3c0839 100644
>>>> --- a/Documentation/devicetree/bindings/net/dsa/b53.txt
>>>> +++ b/Documentation/devicetree/bindings/net/dsa/b53.txt
>>>> @@ -29,6 +29,9 @@ Required properties:
>>>> "brcm,bcm58625-srab"
>>>> "brcm,bcm88312-srab" and the mandatory "brcm,nsp-srab string
>>>>
>>>> + For the BCM11360 SoC, must be:
>>>> + "brcm,bcm11360-srab" and the mandatory "brcm,cygnus-srab string
>>>> +
>>>> For the BCM63xx/33xx SoCs with an integrated switch, must be one of:
>>>> "brcm,bcm3384-switch"
>>>> "brcm,bcm6328-switch"
>>>> diff --git a/drivers/net/dsa/b53/b53_srab.c b/drivers/net/dsa/b53/b53_srab.c
>>>> index 8a62b6a69703..c37ffd1b6833 100644
>>>> --- a/drivers/net/dsa/b53/b53_srab.c
>>>> +++ b/drivers/net/dsa/b53/b53_srab.c
>>>> @@ -364,6 +364,7 @@ static const struct of_device_id b53_srab_of_match[] = {
>>>> { .compatible = "brcm,bcm53018-srab" },
>>>> { .compatible = "brcm,bcm53019-srab" },
>>>> { .compatible = "brcm,bcm5301x-srab" },
>>>> + { .compatible = "brcm,bcm11360-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>>> { .compatible = "brcm,bcm58522-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>>> { .compatible = "brcm,bcm58525-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>>> { .compatible = "brcm,bcm58535-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>>> @@ -371,6 +372,7 @@ static const struct of_device_id b53_srab_of_match[] = {
>>>> { .compatible = "brcm,bcm58623-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>>> { .compatible = "brcm,bcm58625-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>>> { .compatible = "brcm,bcm88312-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>>> + { .compatible = "brcm,cygnus-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>> The device ID should be 0xd300. This is the actual value read from the switch regs.
>>> This also requires an entry in the 'b53_switch_chips' structure in b53_common.c.
>> These are not real ID numbers, these are values that indicate the
>> generation of the switch being embedded into the SoC. Within
>> b53_common.c we don't have to differentiate a Starfighter 2 embedded in
>> BCM11360, NSP, or 7445 or 7278, which is why using 58XX_DEVICE_ID should
>> be good enough.
> Ok. Thanks.
>
> I was under the impression, that these id's could be used in the b53_switch_detect()
> API to auto detect the switch. In that API, the switch ID is read from the
> Management page register.
For external switches that is the case, but for internal/integrated
switches, the ID is not always representative of the switch. This is why
the choice of a chip-type ID was used here while adding support for NSP
to the b53 driver.
--
Florian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/2] net: dsa: b53: Add compatible strings for the Cygnus-family BCM11360.
From: Arun Parameswaran @ 2017-04-24 23:15 UTC (permalink / raw)
To: Florian Fainelli, Eric Anholt, Vivien Didelot, Andrew Lunn,
netdev-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Ray Jui,
Scott Branden, Jon Mason
In-Reply-To: <173c8ff2-6a31-5460-9a3f-8d8ac445a336-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On 17-04-24 04:07 PM, Florian Fainelli wrote:
> On 04/24/2017 04:03 PM, Arun Parameswaran wrote:
>> Hi Eric
>>
>> A comment on the Device ID.
>>
>>
>> On 17-04-24 02:50 PM, Eric Anholt wrote:
>>> Cygnus is a small family of SoCs, of which we currently have
>>> devicetree for BCM11360 and BCM58300. The 11360's B53 is mostly the
>>> same as 58xx, just requiring a tiny bit of setup that was previously
>>> missing.
>>>
>>> Signed-off-by: Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
>>> ---
>>> Documentation/devicetree/bindings/net/dsa/b53.txt | 3 +++
>>> drivers/net/dsa/b53/b53_srab.c | 2 ++
>>> 2 files changed, 5 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/net/dsa/b53.txt b/Documentation/devicetree/bindings/net/dsa/b53.txt
>>> index d6c6e41648d4..49c93d3c0839 100644
>>> --- a/Documentation/devicetree/bindings/net/dsa/b53.txt
>>> +++ b/Documentation/devicetree/bindings/net/dsa/b53.txt
>>> @@ -29,6 +29,9 @@ Required properties:
>>> "brcm,bcm58625-srab"
>>> "brcm,bcm88312-srab" and the mandatory "brcm,nsp-srab string
>>>
>>> + For the BCM11360 SoC, must be:
>>> + "brcm,bcm11360-srab" and the mandatory "brcm,cygnus-srab string
>>> +
>>> For the BCM63xx/33xx SoCs with an integrated switch, must be one of:
>>> "brcm,bcm3384-switch"
>>> "brcm,bcm6328-switch"
>>> diff --git a/drivers/net/dsa/b53/b53_srab.c b/drivers/net/dsa/b53/b53_srab.c
>>> index 8a62b6a69703..c37ffd1b6833 100644
>>> --- a/drivers/net/dsa/b53/b53_srab.c
>>> +++ b/drivers/net/dsa/b53/b53_srab.c
>>> @@ -364,6 +364,7 @@ static const struct of_device_id b53_srab_of_match[] = {
>>> { .compatible = "brcm,bcm53018-srab" },
>>> { .compatible = "brcm,bcm53019-srab" },
>>> { .compatible = "brcm,bcm5301x-srab" },
>>> + { .compatible = "brcm,bcm11360-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>> { .compatible = "brcm,bcm58522-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>> { .compatible = "brcm,bcm58525-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>> { .compatible = "brcm,bcm58535-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>> @@ -371,6 +372,7 @@ static const struct of_device_id b53_srab_of_match[] = {
>>> { .compatible = "brcm,bcm58623-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>> { .compatible = "brcm,bcm58625-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>> { .compatible = "brcm,bcm88312-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>> + { .compatible = "brcm,cygnus-srab", .data = (void *)BCM58XX_DEVICE_ID },
>> The device ID should be 0xd300. This is the actual value read from the switch regs.
>> This also requires an entry in the 'b53_switch_chips' structure in b53_common.c.
> These are not real ID numbers, these are values that indicate the
> generation of the switch being embedded into the SoC. Within
> b53_common.c we don't have to differentiate a Starfighter 2 embedded in
> BCM11360, NSP, or 7445 or 7278, which is why using 58XX_DEVICE_ID should
> be good enough.
Ok. Thanks.
I was under the impression, that these id's could be used in the b53_switch_detect()
API to auto detect the switch. In that API, the switch ID is read from the
Management page register.
>>> { .compatible = "brcm,nsp-srab", .data = (void *)BCM58XX_DEVICE_ID },
>>> { /* sentinel */ },
>>> };
>> Other wise this patch set looks good.
>>
>> I was testing a similar change (except for the above, which doesn't
>> affect the functionality) to get the switch working and it works.
>>
>> Thanks
>> Arun
>>
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/2] net: dsa: b53: Add compatible strings for the Cygnus-family BCM11360.
From: Florian Fainelli @ 2017-04-24 23:07 UTC (permalink / raw)
To: Arun Parameswaran, Eric Anholt, Vivien Didelot, Andrew Lunn,
netdev, Rob Herring, Mark Rutland, devicetree
Cc: linux-arm-kernel, linux-kernel, bcm-kernel-feedback-list, Ray Jui,
Scott Branden, Jon Mason
In-Reply-To: <ee265657-8175-b6c7-a0dc-cec216cd9ede@broadcom.com>
On 04/24/2017 04:03 PM, Arun Parameswaran wrote:
> Hi Eric
>
> A comment on the Device ID.
>
>
> On 17-04-24 02:50 PM, Eric Anholt wrote:
>> Cygnus is a small family of SoCs, of which we currently have
>> devicetree for BCM11360 and BCM58300. The 11360's B53 is mostly the
>> same as 58xx, just requiring a tiny bit of setup that was previously
>> missing.
>>
>> Signed-off-by: Eric Anholt <eric@anholt.net>
>> ---
>> Documentation/devicetree/bindings/net/dsa/b53.txt | 3 +++
>> drivers/net/dsa/b53/b53_srab.c | 2 ++
>> 2 files changed, 5 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/net/dsa/b53.txt b/Documentation/devicetree/bindings/net/dsa/b53.txt
>> index d6c6e41648d4..49c93d3c0839 100644
>> --- a/Documentation/devicetree/bindings/net/dsa/b53.txt
>> +++ b/Documentation/devicetree/bindings/net/dsa/b53.txt
>> @@ -29,6 +29,9 @@ Required properties:
>> "brcm,bcm58625-srab"
>> "brcm,bcm88312-srab" and the mandatory "brcm,nsp-srab string
>>
>> + For the BCM11360 SoC, must be:
>> + "brcm,bcm11360-srab" and the mandatory "brcm,cygnus-srab string
>> +
>> For the BCM63xx/33xx SoCs with an integrated switch, must be one of:
>> "brcm,bcm3384-switch"
>> "brcm,bcm6328-switch"
>> diff --git a/drivers/net/dsa/b53/b53_srab.c b/drivers/net/dsa/b53/b53_srab.c
>> index 8a62b6a69703..c37ffd1b6833 100644
>> --- a/drivers/net/dsa/b53/b53_srab.c
>> +++ b/drivers/net/dsa/b53/b53_srab.c
>> @@ -364,6 +364,7 @@ static const struct of_device_id b53_srab_of_match[] = {
>> { .compatible = "brcm,bcm53018-srab" },
>> { .compatible = "brcm,bcm53019-srab" },
>> { .compatible = "brcm,bcm5301x-srab" },
>> + { .compatible = "brcm,bcm11360-srab", .data = (void *)BCM58XX_DEVICE_ID },
>> { .compatible = "brcm,bcm58522-srab", .data = (void *)BCM58XX_DEVICE_ID },
>> { .compatible = "brcm,bcm58525-srab", .data = (void *)BCM58XX_DEVICE_ID },
>> { .compatible = "brcm,bcm58535-srab", .data = (void *)BCM58XX_DEVICE_ID },
>> @@ -371,6 +372,7 @@ static const struct of_device_id b53_srab_of_match[] = {
>> { .compatible = "brcm,bcm58623-srab", .data = (void *)BCM58XX_DEVICE_ID },
>> { .compatible = "brcm,bcm58625-srab", .data = (void *)BCM58XX_DEVICE_ID },
>> { .compatible = "brcm,bcm88312-srab", .data = (void *)BCM58XX_DEVICE_ID },
>> + { .compatible = "brcm,cygnus-srab", .data = (void *)BCM58XX_DEVICE_ID },
> The device ID should be 0xd300. This is the actual value read from the switch regs.
> This also requires an entry in the 'b53_switch_chips' structure in b53_common.c.
These are not real ID numbers, these are values that indicate the
generation of the switch being embedded into the SoC. Within
b53_common.c we don't have to differentiate a Starfighter 2 embedded in
BCM11360, NSP, or 7445 or 7278, which is why using 58XX_DEVICE_ID should
be good enough.
>> { .compatible = "brcm,nsp-srab", .data = (void *)BCM58XX_DEVICE_ID },
>> { /* sentinel */ },
>> };
> Other wise this patch set looks good.
>
> I was testing a similar change (except for the above, which doesn't
> affect the functionality) to get the switch working and it works.
>
> Thanks
> Arun
>
--
Florian
^ permalink raw reply
* [PATCH v2 2/2] of: Add unit tests for applying overlays
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-04-24 23:05 UTC (permalink / raw)
To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A, Michal Marek
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-kbuild-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493075119-32026-1-git-send-email-frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
Existing overlay unit tests examine individual pieces of the overlay
code. The new tests target the entire process of applying an overlay.
Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
---
There are checkpatch warnings. I have reviewed them and feel they
can be ignored.
drivers/of/fdt.c | 14 +-
drivers/of/of_private.h | 11 +
drivers/of/unittest-data/Makefile | 17 +-
drivers/of/unittest-data/overlay.dts | 53 ++++
drivers/of/unittest-data/overlay_bad_phandle.dts | 20 ++
drivers/of/unittest-data/overlay_base.dts | 80 ++++++
drivers/of/unittest.c | 318 +++++++++++++++++++++++
7 files changed, 505 insertions(+), 8 deletions(-)
create mode 100644 drivers/of/unittest-data/overlay.dts
create mode 100644 drivers/of/unittest-data/overlay_bad_phandle.dts
create mode 100644 drivers/of/unittest-data/overlay_base.dts
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index e5ce4b59e162..e33f7818bc6c 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -31,6 +31,8 @@
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#include <asm/page.h>
+#include "of_private.h"
+
/*
* of_fdt_limit_memory - limit the number of regions in the /memory node
* @limit: maximum entries
@@ -469,11 +471,11 @@ static int unflatten_dt_nodes(const void *blob,
* Returns NULL on failure or the memory chunk containing the unflattened
* device tree on success.
*/
-static void *__unflatten_device_tree(const void *blob,
- struct device_node *dad,
- struct device_node **mynodes,
- void *(*dt_alloc)(u64 size, u64 align),
- bool detached)
+void *__unflatten_device_tree(const void *blob,
+ struct device_node *dad,
+ struct device_node **mynodes,
+ void *(*dt_alloc)(u64 size, u64 align),
+ bool detached)
{
int size;
void *mem;
@@ -1261,6 +1263,8 @@ void __init unflatten_device_tree(void)
/* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
of_alias_scan(early_init_dt_alloc_memory_arch);
+
+ unittest_unflatten_overlay_base();
}
/**
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 18bbb4517e25..cc76b3b81eab 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -55,6 +55,17 @@ static inline int of_property_notify(int action, struct device_node *np,
}
#endif /* CONFIG_OF_DYNAMIC */
+#ifdef CONFIG_OF_UNITTEST
+extern void __init unittest_unflatten_overlay_base(void);
+extern void *__unflatten_device_tree(const void *blob,
+ struct device_node *dad,
+ struct device_node **mynodes,
+ void *(*dt_alloc)(u64 size, u64 align),
+ bool detached);
+#else
+static inline void unittest_unflatten_overlay_base(void) {};
+#endif
+
/**
* General utilities for working with live trees.
*
diff --git a/drivers/of/unittest-data/Makefile b/drivers/of/unittest-data/Makefile
index 1ac5cc01d627..6e00a9c69e58 100644
--- a/drivers/of/unittest-data/Makefile
+++ b/drivers/of/unittest-data/Makefile
@@ -1,7 +1,18 @@
obj-y += testcases.dtb.o
+obj-y += overlay.dtb.o
+obj-y += overlay_bad_phandle.dtb.o
+obj-y += overlay_base.dtb.o
targets += testcases.dtb testcases.dtb.S
+targets += overlay.dtb overlay.dtb.S
+targets += overlay_bad_phandle.dtb overlay_bad_phandle.dtb.S
+targets += overlay_base.dtb overlay_base.dtb.S
-.SECONDARY: \
- $(obj)/testcases.dtb.S \
- $(obj)/testcases.dtb
+.PRECIOUS: \
+ $(obj)/%.dtb.S \
+ $(obj)/%.dtb
+
+# enable creation of __symbols__ node
+DTC_FLAGS_overlay := -@
+DTC_FLAGS_overlay_bad_phandle := -@
+DTC_FLAGS_overlay_base := -@
diff --git a/drivers/of/unittest-data/overlay.dts b/drivers/of/unittest-data/overlay.dts
new file mode 100644
index 000000000000..6cd7e6a0c13e
--- /dev/null
+++ b/drivers/of/unittest-data/overlay.dts
@@ -0,0 +1,53 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+
+ fragment@0 {
+ target = <&electric_1>;
+
+ __overlay__ {
+ status = "ok";
+
+ hvac_2: hvac-large-1 {
+ compatible = "ot,hvac-large";
+ heat-range = < 40 75 >;
+ cool-range = < 65 80 >;
+ };
+ };
+ };
+
+ fragment@1 {
+ target = <&rides_1>;
+
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "ok";
+
+ ride@200 {
+ compatible = "ot,ferris-wheel";
+ reg = < 0x00000200 0x100 >;
+ hvac-provider = < &hvac_2 >;
+ hvac-thermostat = < 27 32 > ;
+ hvac-zones = < 12 5 >;
+ hvac-zone-names = "operator", "snack-bar";
+ spin-controller = < &spin_ctrl_1 3 >;
+ spin-rph = < 30 >;
+ gondolas = < 16 >;
+ gondola-capacity = < 6 >;
+ };
+ };
+ };
+
+ fragment@2 {
+ target = <&lights_2>;
+
+ __overlay__ {
+ status = "ok";
+ color = "purple", "white", "red", "green";
+ rate = < 3 256 >;
+ };
+ };
+
+};
diff --git a/drivers/of/unittest-data/overlay_bad_phandle.dts b/drivers/of/unittest-data/overlay_bad_phandle.dts
new file mode 100644
index 000000000000..270ee885a623
--- /dev/null
+++ b/drivers/of/unittest-data/overlay_bad_phandle.dts
@@ -0,0 +1,20 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+
+ fragment@0 {
+ target = <&electric_1>;
+
+ __overlay__ {
+
+ // This label should cause an error when the overlay
+ // is applied. There is already a phandle value
+ // in the base tree for motor-1.
+ spin_ctrl_1_conflict: motor-1 {
+ accelerate = < 3 >;
+ decelerate = < 5 >;
+ };
+ };
+ };
+};
diff --git a/drivers/of/unittest-data/overlay_base.dts b/drivers/of/unittest-data/overlay_base.dts
new file mode 100644
index 000000000000..5566b27fb61a
--- /dev/null
+++ b/drivers/of/unittest-data/overlay_base.dts
@@ -0,0 +1,80 @@
+/dts-v1/;
+/plugin/;
+
+/*
+ * Base device tree that overlays will be applied against.
+ *
+ * Do not add any properties in node "/".
+ * Do not add any nodes other than "/testcase-data-2" in node "/".
+ * Do not add anything that would result in dtc creating node "/__fixups__".
+ * dtc will create nodes "/__symbols__" and "/__local_fixups__".
+ */
+
+/ {
+ testcase-data-2 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ electric_1: substation@100 {
+ compatible = "ot,big-volts-control";
+ reg = < 0x00000100 0x100 >;
+ status = "disabled";
+
+ hvac_1: hvac-medium-1 {
+ compatible = "ot,hvac-medium";
+ heat-range = < 50 75 >;
+ cool-range = < 60 80 >;
+ };
+
+ spin_ctrl_1: motor-1 {
+ compatible = "ot,ferris-wheel-motor";
+ spin = "clockwise";
+ };
+
+ spin_ctrl_2: motor-8 {
+ compatible = "ot,roller-coaster-motor";
+ };
+ };
+
+ rides_1: fairway-1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ot,rides";
+ status = "disabled";
+ orientation = < 127 >;
+
+ ride@100 {
+ compatible = "ot,roller-coaster";
+ reg = < 0x00000100 0x100 >;
+ hvac-provider = < &hvac_1 >;
+ hvac-thermostat = < 29 > ;
+ hvac-zones = < 14 >;
+ hvac-zone-names = "operator";
+ spin-controller = < &spin_ctrl_2 5 &spin_ctrl_2 7 >;
+ spin-controller-names = "track_1", "track_2";
+ queues = < 2 >;
+ };
+ };
+
+ lights_1: lights@30000 {
+ compatible = "ot,work-lights";
+ reg = < 0x00030000 0x1000 >;
+ status = "disabled";
+ };
+
+ lights_2: lights@40000 {
+ compatible = "ot,show-lights";
+ reg = < 0x00040000 0x1000 >;
+ status = "disabled";
+ rate = < 13 138 >;
+ };
+
+ retail_1: vending@50000 {
+ reg = < 0x00050000 0x1000 >;
+ compatible = "ot,tickets";
+ status = "disabled";
+ };
+
+ };
+};
+
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 62db55b97c10..884f6c1f8ae9 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -8,6 +8,7 @@
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/hashtable.h>
+#include <linux/libfdt.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
@@ -1925,6 +1926,320 @@ static void __init of_unittest_overlay(void)
static inline void __init of_unittest_overlay(void) { }
#endif
+#ifdef CONFIG_OF_OVERLAY
+
+/*
+ * __dtb_ot_begin[] and __dtb_ot_end[] are created by cmd_dt_S_dtb
+ * in scripts/Makefile.lib
+ */
+
+#define OVERLAY_INFO_EXTERN(name) \
+ extern uint8_t __dtb_##name##_begin[]; \
+ extern uint8_t __dtb_##name##_end[]
+
+#define OVERLAY_INFO(name, expected) \
+{ .dtb_begin = __dtb_##name##_begin, \
+ .dtb_end = __dtb_##name##_end, \
+ .expected_result = expected, \
+}
+
+struct overlay_info {
+ uint8_t *dtb_begin;
+ uint8_t *dtb_end;
+ void *data;
+ struct device_node *np_overlay;
+ int expected_result;
+ int overlay_id;
+};
+
+OVERLAY_INFO_EXTERN(overlay_base);
+OVERLAY_INFO_EXTERN(overlay);
+OVERLAY_INFO_EXTERN(overlay_bad_phandle);
+
+/* order of entries is hard-coded into users of overlays[] */
+struct overlay_info overlays[] = {
+ OVERLAY_INFO(overlay_base, -9999),
+ OVERLAY_INFO(overlay, 0),
+ OVERLAY_INFO(overlay_bad_phandle, -EINVAL),
+ {}
+};
+
+static struct device_node *overlay_base_root;
+
+/*
+ * Create base device tree for the overlay unittest.
+ *
+ * This is called from very early boot code.
+ *
+ * Do as much as possible the same way as done in __unflatten_device_tree
+ * and other early boot steps for the normal FDT so that the overlay base
+ * unflattened tree will have the same characteristics as the real tree
+ * (such as having memory allocated by the early allocator). The goal
+ * is to test "the real thing" as much as possible, and test "test setup
+ * code" as little as possible.
+ *
+ * Have to stop before resolving phandles, because that uses kmalloc.
+ */
+void __init unittest_unflatten_overlay_base(void)
+{
+ struct overlay_info *info;
+ u32 data_size;
+ u32 size;
+
+ info = &overlays[0];
+
+ if (info->expected_result != -9999) {
+ pr_err("No dtb 'overlay_base' to attach\n");
+ return;
+ }
+
+ data_size = info->dtb_end - info->dtb_begin;
+ if (!data_size) {
+ pr_err("No dtb 'overlay_base' to attach\n");
+ return;
+ }
+
+ size = fdt_totalsize(info->dtb_begin);
+ if (size != data_size) {
+ pr_err("dtb 'overlay_base' header totalsize != actual size");
+ return;
+ }
+
+ info->data = early_init_dt_alloc_memory_arch(size,
+ roundup_pow_of_two(FDT_V17_SIZE));
+ if (!info->data) {
+ pr_err("alloc for dtb 'overlay_base' failed");
+ return;
+ }
+
+ memcpy(info->data, info->dtb_begin, size);
+
+ __unflatten_device_tree(info->data, NULL, &info->np_overlay,
+ early_init_dt_alloc_memory_arch, true);
+ overlay_base_root = info->np_overlay;
+}
+
+/*
+ * The purpose of of_unittest_overlay_data_add is to add an
+ * overlay in the normal fashion. This is a test of the whole
+ * picture, instead of testing individual elements.
+ *
+ * A secondary purpose is to be able to verify that the contents of
+ * /proc/device-tree/ contains the updated structure and values from
+ * the overlay. That must be verified separately in user space.
+ *
+ * Return 0 on unexpected error.
+ */
+static int __init overlay_data_add(int onum)
+{
+ struct overlay_info *info;
+ int k;
+ int ret;
+ u32 size;
+ u32 size_from_header;
+
+ for (k = 0, info = overlays; info; info++, k++) {
+ if (k == onum)
+ break;
+ }
+ if (onum > k)
+ return 0;
+
+ size = info->dtb_end - info->dtb_begin;
+ if (!size) {
+ pr_err("no overlay to attach, %d\n", onum);
+ ret = 0;
+ }
+
+ size_from_header = fdt_totalsize(info->dtb_begin);
+ if (size_from_header != size) {
+ pr_err("overlay header totalsize != actual size, %d", onum);
+ return 0;
+ }
+
+ /*
+ * Must create permanent copy of FDT because of_fdt_unflatten_tree()
+ * will create pointers to the passed in FDT in the EDT.
+ */
+ info->data = kmemdup(info->dtb_begin, size, GFP_KERNEL);
+ if (!info->data) {
+ pr_err("unable to allocate memory for data, %d\n", onum);
+ return 0;
+ }
+
+ of_fdt_unflatten_tree(info->data, NULL, &info->np_overlay);
+ if (!info->np_overlay) {
+ pr_err("unable to unflatten overlay, %d\n", onum);
+ ret = 0;
+ goto out_free_data;
+ }
+ of_node_set_flag(info->np_overlay, OF_DETACHED);
+
+ ret = of_resolve_phandles(info->np_overlay);
+ if (ret) {
+ pr_err("resolve ot phandles (ret=%d), %d\n", ret, onum);
+ goto out_free_np_overlay;
+ }
+
+ ret = of_overlay_create(info->np_overlay);
+ if (ret < 0) {
+ pr_err("of_overlay_create() (ret=%d), %d\n", ret, onum);
+ goto out_free_np_overlay;
+ } else {
+ info->overlay_id = ret;
+ ret = 0;
+ }
+
+ pr_debug("__dtb_overlay_begin applied, overlay id %d\n", ret);
+
+ goto out;
+
+out_free_np_overlay:
+ /*
+ * info->np_overlay is the unflattened device tree
+ * It has not been spliced into the live tree.
+ */
+
+ /* todo: function to free unflattened device tree */
+
+out_free_data:
+ kfree(info->data);
+
+out:
+ return (ret == info->expected_result);
+}
+
+/*
+ * The purpose of of_unittest_overlay_high_level is to add an overlay
+ * in the normal fashion. This is a test of the whole picture,
+ * instead of individual elements.
+ *
+ * The first part of the function is _not_ normal overlay usage; it is
+ * finishing splicing the base overlay device tree into the live tree.
+ */
+static __init void of_unittest_overlay_high_level(void)
+{
+ struct device_node *last_sibling;
+ struct device_node *np;
+ struct device_node *of_symbols;
+ struct device_node *overlay_base_symbols;
+ struct device_node **pprev;
+ struct property *prop;
+ int ret;
+
+ if (!overlay_base_root) {
+ unittest(0, "overlay_base_root not initialized\n");
+ return;
+ }
+
+ /*
+ * Could not fixup phandles in unittest_unflatten_overlay_base()
+ * because kmalloc() was not yet available.
+ */
+ of_resolve_phandles(overlay_base_root);
+
+ /*
+ * do not allow overlay_base to duplicate any node already in
+ * tree, this greatly simplifies the code
+ */
+
+ /*
+ * remove overlay_base_root node "__local_fixups", after
+ * being used by of_resolve_phandles()
+ */
+ pprev = &overlay_base_root->child;
+ for (np = overlay_base_root->child; np; np = np->sibling) {
+ if (!of_node_cmp(np->name, "__local_fixups__")) {
+ *pprev = np->sibling;
+ break;
+ }
+ pprev = &np->sibling;
+ }
+
+ /* remove overlay_base_root node "__symbols__" if in live tree */
+ of_symbols = of_get_child_by_name(of_root, "__symbols__");
+ if (of_symbols) {
+ /* will have to graft properties from node into live tree */
+ pprev = &overlay_base_root->child;
+ for (np = overlay_base_root->child; np; np = np->sibling) {
+ if (!of_node_cmp(np->name, "__symbols__")) {
+ overlay_base_symbols = np;
+ *pprev = np->sibling;
+ break;
+ }
+ pprev = &np->sibling;
+ }
+ }
+
+ for (np = overlay_base_root->child; np; np = np->sibling) {
+ if (of_get_child_by_name(of_root, np->name)) {
+ unittest(0, "illegal node name in overlay_base %s",
+ np->name);
+ return;
+ }
+ }
+
+ /*
+ * overlay 'overlay_base' is not allowed to have root
+ * properties, so only need to splice nodes into main device tree.
+ *
+ * root node of *overlay_base_root will not be freed, it is lost
+ * memory.
+ */
+
+ for (np = overlay_base_root->child; np; np = np->sibling)
+ np->parent = of_root;
+
+ mutex_lock(&of_mutex);
+
+ for (np = of_root->child; np; np = np->sibling)
+ last_sibling = np;
+
+ if (last_sibling)
+ last_sibling->sibling = overlay_base_root->child;
+ else
+ of_root->child = overlay_base_root->child;
+
+ for_each_of_allnodes_from(overlay_base_root, np)
+ __of_attach_node_sysfs(np);
+
+ if (of_symbols) {
+ for_each_property_of_node(overlay_base_symbols, prop) {
+ ret = __of_add_property(of_symbols, prop);
+ if (ret) {
+ unittest(0,
+ "duplicate property '%s' in overlay_base node __symbols__",
+ prop->name);
+ return;
+ }
+ ret = __of_add_property_sysfs(of_symbols, prop);
+ if (ret) {
+ unittest(0,
+ "unable to add property '%s' in overlay_base node __symbols__ to sysfs",
+ prop->name);
+ return;
+ }
+ }
+ }
+
+ mutex_unlock(&of_mutex);
+
+
+ /* now do the normal overlay usage test */
+
+ unittest(overlay_data_add(1),
+ "Adding overlay 'overlay' failed\n");
+
+ unittest(overlay_data_add(2),
+ "Adding overlay 'overlay_bad_phandle' failed\n");
+}
+
+#else
+
+static inline __init void of_unittest_overlay_high_level(void) {}
+
+#endif
+
static int __init of_unittest(void)
{
struct device_node *np;
@@ -1962,6 +2277,9 @@ static int __init of_unittest(void)
/* Double check linkage after removing testcase data */
of_unittest_check_tree_linkage();
+
+ of_unittest_overlay_high_level();
+
pr_info("end of unittest - %i passed, %i failed\n",
unittest_results.passed, unittest_results.failed);
--
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 1/2] of: support dtc compiler flags for overlays
From: frowand.list @ 2017-04-24 23:05 UTC (permalink / raw)
To: Rob Herring, stephen.boyd, Michal Marek
Cc: devicetree, linux-kernel, linux-kbuild
In-Reply-To: <1493075119-32026-1-git-send-email-frowand.list@gmail.com>
From: Frank Rowand <frank.rowand@sony.com>
The dtc compiler version that adds initial support was available
in 4.11-rc1. Add the ability to set the dtc compiler flags needed
by overlays.
Signed-off-by: Frank Rowand <frank.rowand@sony.com>
---
scripts/Makefile.lib | 2 ++
1 file changed, 2 insertions(+)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0a07f9014944..0bbec480d323 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -283,6 +283,8 @@ ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),)
DTC_FLAGS += -Wno-unit_address_vs_reg
endif
+DTC_FLAGS += $(DTC_FLAGS_$(basetarget))
+
# Generate an assembly file to wrap the output of the device tree compiler
quiet_cmd_dt_S_dtb= DTB $@
cmd_dt_S_dtb= \
--
Frank Rowand <frank.rowand@sony.com>
^ permalink raw reply related
* [PATCH v2 0/2] of: Add unit tests for applying overlays
From: frowand.list @ 2017-04-24 23:05 UTC (permalink / raw)
To: Rob Herring, stephen.boyd, Michal Marek
Cc: devicetree, linux-kernel, linux-kbuild
From: Frank Rowand <frank.rowand@sony.com>
Existing overlay unit tests examine individual pieces of the overlay
code. The new tests target the entire process of applying an overlay.
Changes from v1:
- Move overlay base dtb unflattening into unittest.c. Call from fdt.c.
- Clarify file and variable names, 'overlay_test_' instead of 'ot_'
- Use proper naming convention for node names.
- A few added comments.
- Improve error messages in the new tests.
Frank Rowand (2):
of: support dtc compiler flags for device tree overlays
of: Add unit tests for applying overlays.
drivers/of/fdt.c | 14 +-
drivers/of/of_private.h | 11 +
drivers/of/unittest-data/Makefile | 17 +-
drivers/of/unittest-data/overlay.dts | 53 ++++
drivers/of/unittest-data/overlay_bad_phandle.dts | 20 ++
drivers/of/unittest-data/overlay_base.dts | 80 ++++++
drivers/of/unittest.c | 318 +++++++++++++++++++++++
scripts/Makefile.lib | 2 +
8 files changed, 507 insertions(+), 8 deletions(-)
create mode 100644 drivers/of/unittest-data/overlay.dts
create mode 100644 drivers/of/unittest-data/overlay_bad_phandle.dts
create mode 100644 drivers/of/unittest-data/overlay_base.dts
--
Frank Rowand <frank.rowand@sony.com>
^ 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