* RE: [PATCH V4 2/5] input: keyboard: imx_sc: Add i.MX system controller key support
From: Anson Huang @ 2019-09-17 2:42 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: mark.rutland@arm.com, ulf.hansson@linaro.org, Jacky Bai,
catalin.marinas@arm.com, Peng Fan, stefan@agner.ch,
bjorn.andersson@linaro.org, Leonard Crestez, will@kernel.org,
festevam@gmail.com, yuehaibing@huawei.com,
marcin.juszkiewicz@linaro.org, cw00.choi@samsung.com,
jagan@amarulasolutions.com, linux-input@vger.kernel.org,
ronald@innovation.ch, dl-linux-imx, devicetree@vger.kernel.org,
arnd@arndb.de, s.hauer@pengutronix.de, mripard@kernel.org,
m.felsch@pengutronix.de, enric.balletbo@collabora.com,
robh+dt@kernel.org, andriy.shevchenko@linux.intel.com,
Daniel Baluta, linux-arm-kernel@lists.infradead.org, Aisheng Dong,
Andy Duan, linux-kernel@vger.kernel.org, dinguyen@kernel.org,
kernel@pengutronix.de, olof@lixom.net, shawnguo@kernel.org
In-Reply-To: <20190916235330.GI237523@dtor-ws>
Hi, Dmitry
> On Mon, Sep 16, 2019 at 10:52:50AM +0800, Anson Huang wrote:
> > i.MX8QXP is an ARMv8 SoC which has a Cortex-M4 system controller
> > inside, the system controller is in charge of controlling power, clock
> > and scu key etc..
> >
> > Adds i.MX system controller key driver support, Linux kernel has to
> > communicate with system controller via MU (message unit) IPC to get
> > scu key's status.
> >
> > Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> > ---
> > Changes since V3:
> > - switch the debounce and repeat interval time for delay work
> schdule;
> > - add .remove to handle group irq and notify etc..
> > ---
> > drivers/input/keyboard/Kconfig | 7 ++
> > drivers/input/keyboard/Makefile | 1 +
> > drivers/input/keyboard/imx_sc_key.c | 190
> > ++++++++++++++++++++++++++++++++++++
> > 3 files changed, 198 insertions(+)
> > create mode 100644 drivers/input/keyboard/imx_sc_key.c
> >
> > diff --git a/drivers/input/keyboard/Kconfig
> > b/drivers/input/keyboard/Kconfig index 8911bc2..00f8428 100644
> > --- a/drivers/input/keyboard/Kconfig
> > +++ b/drivers/input/keyboard/Kconfig
> > @@ -469,6 +469,13 @@ config KEYBOARD_IMX
> > To compile this driver as a module, choose M here: the
> > module will be called imx_keypad.
> >
> > +config KEYBOARD_IMX_SC_KEY
> > + tristate "IMX SCU Key Driver"
> > + depends on IMX_SCU
> > + help
> > + This is the system controller key driver for NXP i.MX SoCs with
> > + system controller inside.
> > +
> > config KEYBOARD_NEWTON
> > tristate "Newton keyboard"
> > select SERIO
> > diff --git a/drivers/input/keyboard/Makefile
> > b/drivers/input/keyboard/Makefile index 9510325..f5b1752 100644
> > --- a/drivers/input/keyboard/Makefile
> > +++ b/drivers/input/keyboard/Makefile
> > @@ -29,6 +29,7 @@ obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
> > obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
> > obj-$(CONFIG_KEYBOARD_IPAQ_MICRO) += ipaq-micro-keys.o
> > obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o
> > +obj-$(CONFIG_KEYBOARD_IMX_SC_KEY) += imx_sc_key.o
> > obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
> > obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
> > obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
> > diff --git a/drivers/input/keyboard/imx_sc_key.c
> > b/drivers/input/keyboard/imx_sc_key.c
> > new file mode 100644
> > index 0000000..59c68fa
> > --- /dev/null
> > +++ b/drivers/input/keyboard/imx_sc_key.c
> > @@ -0,0 +1,190 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2019 NXP.
> > + */
> > +
> > +#include <linux/device.h>
> > +#include <linux/err.h>
> > +#include <linux/firmware/imx/sci.h>
> > +#include <linux/init.h>
> > +#include <linux/input.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/jiffies.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/platform_device.h>
> > +
> > +#define DEBOUNCE_TIME 100
> > +#define REPEAT_INTERVAL 60
> > +
> > +#define SC_IRQ_BUTTON 1
> > +#define SC_IRQ_GROUP_WAKE 3
> > +#define IMX_SC_MISC_FUNC_GET_BUTTON_STATUS 18
> > +
> > +struct imx_key_drv_data {
> > + int keycode;
> > + bool keystate; /* 1: pressed, 0: release */
> > + bool delay_check;
> > + struct delayed_work check_work;
> > + struct input_dev *input;
> > + struct imx_sc_ipc *key_ipc_handle;
> > + struct notifier_block key_notifier;
> > +};
> > +
> > +struct imx_sc_msg_key {
> > + struct imx_sc_rpc_msg hdr;
> > + u8 state;
> > +};
> > +
> > +static int imx_sc_key_notify(struct notifier_block *nb,
> > + unsigned long event, void *group) {
> > + struct imx_key_drv_data *priv =
> > + container_of(nb,
> > + struct imx_key_drv_data,
> > + key_notifier);
> > +
> > + if ((event & SC_IRQ_BUTTON) && (*(u8 *)group ==
> SC_IRQ_GROUP_WAKE)
> > + && !priv->delay_check) {
> > + priv->delay_check = 1;
> > + schedule_delayed_work(&priv->check_work,
> > + msecs_to_jiffies(DEBOUNCE_TIME));
>
> If I am reading this right, you are trying to avoid scheduling the work again if
> it is already scheduled. You do not need to do that, as
> schedule_delayed_work() will take care of that (if you want to make sure the
> work is re-scheduled with updated expiration, you need to use
> mod_delayed_work).
The original code here is to skip the event of button release, try to ONLY handle the press interrupt, the release
event is handled by busy loop check, but I double check the SCU FW's behavior, it does NOT send out interrupt
for button release event at all, so it is NOT needed any more, I will remove the priv->delay_check completely in this driver.
>
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static void imx_sc_check_for_events(struct work_struct *work) {
> > + struct imx_key_drv_data *priv =
> > + container_of(work,
> > + struct imx_key_drv_data,
> > + check_work.work);
> > + struct input_dev *input = priv->input;
> > + struct imx_sc_msg_key msg;
> > + struct imx_sc_rpc_msg *hdr = &msg.hdr;
> > + bool state;
> > + int ret;
> > +
> > + hdr->ver = IMX_SC_RPC_VERSION;
> > + hdr->svc = IMX_SC_RPC_SVC_MISC;
> > + hdr->func = IMX_SC_MISC_FUNC_GET_BUTTON_STATUS;
> > + hdr->size = 1;
> > +
> > + ret = imx_scu_call_rpc(priv->key_ipc_handle, &msg, true);
> > + if (ret) {
> > + dev_err(&input->dev, "read imx sc key failed, ret %d\n", ret);
> > + return;
> > + }
> > +
> > + state = (bool)msg.state;
> > +
> > + if (!state && !priv->keystate)
> > + state = true;
>
> This needs an explanation please.
This is to handle the quick press of button, e.g., when button is pressed and released very quickly,
when the delay work is scheduled, the button state read from SCU FW is actually a release state (0),
the press state is (1), so the quick press/release will be ignored.
However, after double check and test, I think this should be handled by debounce time, if the button is pressed/release
very quickly, the event should be ignored, I will remove it and reduce the debounce time to 30mS, previous 100mS
is too long, using 30mS as debounce time, I did NOT see similar issue no matter how quick I press/release the button.
>
> > +
> > + if (state ^ priv->keystate) {
> > + pm_wakeup_event(input->dev.parent, 0);
>
> I'd expect this happening in imx_sc_key_notify() so that the device would
> have a change to run this work.
Agreed, will move it to the imx_sc_key_notify().
>
> > + priv->keystate = state;
> > + input_event(input, EV_KEY, priv->keycode, state);
> > + input_sync(input);
> > + if (!state)
> > + priv->delay_check = 0;
> > + pm_relax(priv->input->dev.parent);
>
> Are you sure you want to call pm_relax() unconditionally, and not when state
> == false (i.e. button released)?
Agreed, will make sure ONLY call it when button is released which indicates the event
is finished.
>
> > + }
> > +
> > + if (state)
> > + schedule_delayed_work(&priv->check_work,
> > + msecs_to_jiffies(REPEAT_INTERVAL));
> > +}
> > +
> > +static int imx_sc_key_probe(struct platform_device *pdev) {
> > + struct device_node *np = pdev->dev.of_node;
> > + static struct imx_key_drv_data *priv;
> > + struct input_dev *input;
> > + int ret;
> > +
> > + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> > + if (!priv)
> > + return -ENOMEM;
> > +
> > + ret = imx_scu_get_handle(&priv->key_ipc_handle);
> > + if (ret)
> > + return ret;
> > +
> > + if (of_property_read_u32(np, "linux,keycode", &priv->keycode)) {
> > + dev_err(&pdev->dev, "missing KEY_POWER in DT\n");
> > + return -EINVAL;
> > + }
> > +
> > + INIT_DELAYED_WORK(&priv->check_work,
> imx_sc_check_for_events);
> > +
> > + input = devm_input_allocate_device(&pdev->dev);
> > + if (!input) {
> > + dev_err(&pdev->dev, "failed to allocate the input device\n");
> > + return -ENOMEM;
> > + }
> > +
> > + input->name = pdev->name;
> > + input->phys = "imx-sc-key/input0";
> > + input->id.bustype = BUS_HOST;
> > +
> > + input_set_capability(input, EV_KEY, priv->keycode);
> > +
> > + ret = input_register_device(input);
> > + if (ret) {
>
> Could you please rename this (and elsewhere) from 'ret' to 'error'?
OK.
>
> > + dev_err(&pdev->dev, "failed to register input device\n");
> > + return ret;
> > + }
> > +
> > + priv->input = input;
> > + platform_set_drvdata(pdev, priv);
> > +
> > + ret = imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE,
> SC_IRQ_BUTTON, true);
> > + if (ret) {
> > + dev_warn(&pdev->dev, "enable scu group irq failed\n");
> > + return ret;
> > + }
> > +
> > + priv->key_notifier.notifier_call = imx_sc_key_notify;
> > + ret = imx_scu_irq_register_notifier(&priv->key_notifier);
> > + if (ret) {
> > + imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE,
> SC_IRQ_BUTTON, false);
> > + dev_warn(&pdev->dev, "register scu notifier failed\n");
>
> return error;
> > + }
> > +
> > + return ret;
>
> return 0;
OK.
Thanks,
Anson.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH V5 1/5] dt-bindings: fsl: scu: add scu key binding
From: Anson Huang @ 2019-09-17 2:55 UTC (permalink / raw)
To: robh+dt, mark.rutland, shawnguo, s.hauer, kernel, festevam,
catalin.marinas, will, dmitry.torokhov, aisheng.dong, ulf.hansson,
fugang.duan, peng.fan, leonard.crestez, daniel.baluta, olof,
mripard, arnd, jagan, dinguyen, bjorn.andersson,
marcin.juszkiewicz, andriy.shevchenko, yuehaibing, cw00.choi,
enric.balletbo, m.felsch, ping.bai, ronald, stefan, devicetree,
linux-kernel, linux-arm-kernel, linux-input
Cc: Linux-imx
NXP i.MX8QXP is an ARMv8 SoC with a Cortex-M4 core inside as
system controller, the system controller is in charge of system
power, clock and scu key event etc. management, Linux kernel has
to communicate with system controller via MU (message unit) IPC
to get scu key event, add binding doc for i.MX system controller
key driver.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
No changes.
---
.../devicetree/bindings/arm/freescale/fsl,scu.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
index c149fad..5eab7d0 100644
--- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
@@ -157,6 +157,15 @@ Required properties:
Optional properties:
- timeout-sec: contains the watchdog timeout in seconds.
+SCU key bindings based on SCU Message Protocol
+------------------------------------------------------------
+
+Required properties:
+- compatible: should be:
+ "fsl,imx8qxp-sc-key"
+ followed by "fsl,imx-sc-key";
+- linux,keycodes: See Documentation/devicetree/bindings/input/keys.txt
+
Example (imx8qxp):
-------------
aliases {
@@ -220,6 +229,11 @@ firmware {
compatible = "fsl,imx8qxp-sc-rtc";
};
+ scu_key: scu-key {
+ compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
+ linux,keycode = <KEY_POWER>;
+ };
+
watchdog {
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
timeout-sec = <60>;
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V5 2/5] input: keyboard: imx_sc: Add i.MX system controller key support
From: Anson Huang @ 2019-09-17 2:55 UTC (permalink / raw)
To: robh+dt, mark.rutland, shawnguo, s.hauer, kernel, festevam,
catalin.marinas, will, dmitry.torokhov, aisheng.dong, ulf.hansson,
fugang.duan, peng.fan, leonard.crestez, daniel.baluta, olof,
mripard, arnd, jagan, dinguyen, bjorn.andersson,
marcin.juszkiewicz, andriy.shevchenko, yuehaibing, cw00.choi,
enric.balletbo, m.felsch, ping.bai, ronald, stefan, devicetree,
linux-kernel, linux-arm-kernel, linux-input
Cc: Linux-imx
In-Reply-To: <1568688939-13649-1-git-send-email-Anson.Huang@nxp.com>
i.MX8QXP is an ARMv8 SoC which has a Cortex-M4 system controller
inside, the system controller is in charge of controlling power,
clock and scu key etc..
Adds i.MX system controller key driver support, Linux kernel has
to communicate with system controller via MU (message unit) IPC
to get scu key's status.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
Changes since V4:
- reduce debounce time from 100mS to 30mS;
- remove unnecessary delay_check for button release interrupt which is NOT existing at all;
- using error instead of ret;
- move pm_wakeup_event() to interrupt notify and ONLY calling pm_relax() when button is released;
- remove unnecessary logic code of avoiding quick button press/release.
---
drivers/input/keyboard/Kconfig | 7 ++
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/imx_sc_key.c | 184 ++++++++++++++++++++++++++++++++++++
3 files changed, 192 insertions(+)
create mode 100644 drivers/input/keyboard/imx_sc_key.c
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 8911bc2..00f8428 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -469,6 +469,13 @@ config KEYBOARD_IMX
To compile this driver as a module, choose M here: the
module will be called imx_keypad.
+config KEYBOARD_IMX_SC_KEY
+ tristate "IMX SCU Key Driver"
+ depends on IMX_SCU
+ help
+ This is the system controller key driver for NXP i.MX SoCs with
+ system controller inside.
+
config KEYBOARD_NEWTON
tristate "Newton keyboard"
select SERIO
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 9510325..f5b1752 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
obj-$(CONFIG_KEYBOARD_IPAQ_MICRO) += ipaq-micro-keys.o
obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o
+obj-$(CONFIG_KEYBOARD_IMX_SC_KEY) += imx_sc_key.o
obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
diff --git a/drivers/input/keyboard/imx_sc_key.c b/drivers/input/keyboard/imx_sc_key.c
new file mode 100644
index 0000000..173e377
--- /dev/null
+++ b/drivers/input/keyboard/imx_sc_key.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/firmware/imx/sci.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#define DEBOUNCE_TIME 30
+#define REPEAT_INTERVAL 60
+
+#define SC_IRQ_BUTTON 1
+#define SC_IRQ_GROUP_WAKE 3
+#define IMX_SC_MISC_FUNC_GET_BUTTON_STATUS 18
+
+struct imx_key_drv_data {
+ int keycode;
+ bool keystate; /* 1: pressed, 0: release */
+ struct delayed_work check_work;
+ struct input_dev *input;
+ struct imx_sc_ipc *key_ipc_handle;
+ struct notifier_block key_notifier;
+};
+
+struct imx_sc_msg_key {
+ struct imx_sc_rpc_msg hdr;
+ u8 state;
+};
+
+static int imx_sc_key_notify(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+ struct imx_key_drv_data *priv =
+ container_of(nb,
+ struct imx_key_drv_data,
+ key_notifier);
+
+ if ((event & SC_IRQ_BUTTON) && (*(u8 *)group == SC_IRQ_GROUP_WAKE)) {
+ schedule_delayed_work(&priv->check_work,
+ msecs_to_jiffies(DEBOUNCE_TIME));
+ pm_wakeup_event(priv->input->dev.parent, 0);
+ }
+
+ return 0;
+}
+
+static void imx_sc_check_for_events(struct work_struct *work)
+{
+ struct imx_key_drv_data *priv =
+ container_of(work,
+ struct imx_key_drv_data,
+ check_work.work);
+ struct input_dev *input = priv->input;
+ struct imx_sc_msg_key msg;
+ struct imx_sc_rpc_msg *hdr = &msg.hdr;
+ bool state;
+ int error;
+
+ hdr->ver = IMX_SC_RPC_VERSION;
+ hdr->svc = IMX_SC_RPC_SVC_MISC;
+ hdr->func = IMX_SC_MISC_FUNC_GET_BUTTON_STATUS;
+ hdr->size = 1;
+
+ error = imx_scu_call_rpc(priv->key_ipc_handle, &msg, true);
+ if (error) {
+ dev_err(&input->dev, "read imx sc key failed, ret %d\n", ret);
+ return;
+ }
+
+ state = (bool)msg.state;
+
+ if (state ^ priv->keystate) {
+ priv->keystate = state;
+ input_event(input, EV_KEY, priv->keycode, state);
+ input_sync(input);
+ if (!priv->keystate)
+ pm_relax(priv->input->dev.parent);
+ }
+
+ if (state)
+ schedule_delayed_work(&priv->check_work,
+ msecs_to_jiffies(REPEAT_INTERVAL));
+}
+
+static int imx_sc_key_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ static struct imx_key_drv_data *priv;
+ struct input_dev *input;
+ int error;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ error = imx_scu_get_handle(&priv->key_ipc_handle);
+ if (error)
+ return error;
+
+ if (of_property_read_u32(np, "linux,keycode", &priv->keycode)) {
+ dev_err(&pdev->dev, "missing KEY_POWER in DT\n");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&priv->check_work, imx_sc_check_for_events);
+
+ input = devm_input_allocate_device(&pdev->dev);
+ if (!input) {
+ dev_err(&pdev->dev, "failed to allocate the input device\n");
+ return -ENOMEM;
+ }
+
+ input->name = pdev->name;
+ input->phys = "imx-sc-key/input0";
+ input->id.bustype = BUS_HOST;
+
+ input_set_capability(input, EV_KEY, priv->keycode);
+
+ error = input_register_device(input);
+ if (error) {
+ dev_err(&pdev->dev, "failed to register input device\n");
+ return error;
+ }
+
+ priv->input = input;
+ platform_set_drvdata(pdev, priv);
+
+ error = imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, true);
+ if (error) {
+ dev_warn(&pdev->dev, "enable scu group irq failed\n");
+ return error;
+ }
+
+ priv->key_notifier.notifier_call = imx_sc_key_notify;
+ error = imx_scu_irq_register_notifier(&priv->key_notifier);
+ if (error) {
+ imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, false);
+ dev_warn(&pdev->dev, "register scu notifier failed\n");
+ return error;
+ }
+
+ return 0;
+}
+
+static int imx_sc_key_remove(struct platform_device *pdev)
+{
+ struct imx_key_drv_data *priv = platform_get_drvdata(pdev);
+
+ imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, false);
+ imx_scu_irq_unregister_notifier(&priv->key_notifier);
+ cancel_delayed_work_sync(&priv->check_work);
+
+ return 0;
+}
+
+static const struct of_device_id imx_sc_key_ids[] = {
+ { .compatible = "fsl,imx-sc-key" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_sc_key_ids);
+
+static struct platform_driver imx_sc_key_driver = {
+ .driver = {
+ .name = "imx-sc-key",
+ .of_match_table = imx_sc_key_ids,
+ },
+ .probe = imx_sc_key_probe,
+ .remove = imx_sc_key_remove,
+};
+module_platform_driver(imx_sc_key_driver);
+
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_DESCRIPTION("i.MX System Controller Key Driver");
+MODULE_LICENSE("GPL v2");
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V5 3/5] arm64: dts: imx8qxp: Add scu key node
From: Anson Huang @ 2019-09-17 2:55 UTC (permalink / raw)
To: robh+dt, mark.rutland, shawnguo, s.hauer, kernel, festevam,
catalin.marinas, will, dmitry.torokhov, aisheng.dong, ulf.hansson,
fugang.duan, peng.fan, leonard.crestez, daniel.baluta, olof,
mripard, arnd, jagan, dinguyen, bjorn.andersson,
marcin.juszkiewicz, andriy.shevchenko, yuehaibing, cw00.choi,
enric.balletbo, m.felsch, ping.bai, ronald, stefan, devicetree,
linux-kernel, linux-arm-kernel, linux-input
Cc: Linux-imx
In-Reply-To: <1568688939-13649-1-git-send-email-Anson.Huang@nxp.com>
Add scu key node for i.MX8QXP, disabled by default as it
depends on board design.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
No changes.
---
arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 1133b41..71e38c1 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -8,6 +8,7 @@
#include <dt-bindings/clock/imx8-clock.h>
#include <dt-bindings/firmware/imx/rsrc.h>
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/pinctrl/pads-imx8qxp.h>
@@ -174,6 +175,12 @@
#power-domain-cells = <1>;
};
+ scu_key: scu-key {
+ compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
+ linux,keycode = <KEY_POWER>;
+ status = "disabled";
+ };
+
rtc: rtc {
compatible = "fsl,imx8qxp-sc-rtc";
};
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V5 4/5] arm64: dts: imx8qxp-mek: Enable scu key
From: Anson Huang @ 2019-09-17 2:55 UTC (permalink / raw)
To: robh+dt, mark.rutland, shawnguo, s.hauer, kernel, festevam,
catalin.marinas, will, dmitry.torokhov, aisheng.dong, ulf.hansson,
fugang.duan, peng.fan, leonard.crestez, daniel.baluta, olof,
mripard, arnd, jagan, dinguyen, bjorn.andersson,
marcin.juszkiewicz, andriy.shevchenko, yuehaibing, cw00.choi,
enric.balletbo, m.felsch, ping.bai, ronald, stefan, devicetree,
linux-kernel, linux-arm-kernel, linux-input
Cc: Linux-imx
In-Reply-To: <1568688939-13649-1-git-send-email-Anson.Huang@nxp.com>
Enable scu key for i.MX8QXP MEK board.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
No changes.
---
arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 1946805..88dd9132 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -234,3 +234,7 @@
&adma_dsp {
status = "okay";
};
+
+&scu_key {
+ status = "okay";
+};
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V5 5/5] arm64: defconfig: Enable CONFIG_KEYBOARD_IMX_SC_KEY as module
From: Anson Huang @ 2019-09-17 2:55 UTC (permalink / raw)
To: robh+dt, mark.rutland, shawnguo, s.hauer, kernel, festevam,
catalin.marinas, will, dmitry.torokhov, aisheng.dong, ulf.hansson,
fugang.duan, peng.fan, leonard.crestez, daniel.baluta, olof,
mripard, arnd, jagan, dinguyen, bjorn.andersson,
marcin.juszkiewicz, andriy.shevchenko, yuehaibing, cw00.choi,
enric.balletbo, m.felsch, ping.bai, ronald, stefan, devicetree,
linux-kernel, linux-arm-kernel, linux-input
Cc: Linux-imx
In-Reply-To: <1568688939-13649-1-git-send-email-Anson.Huang@nxp.com>
Select CONFIG_KEYBOARD_IMX_SC_KEY as module by default to
support i.MX8QXP scu key driver.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
No changes.
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0a70e10..9c83014 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -314,6 +314,7 @@ CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_ADC=m
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_SNVS_PWRKEY=m
+CONFIG_KEYBOARD_IMX_SC_KEY=m
CONFIG_KEYBOARD_CROS_EC=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH RESEND V5 1/5] dt-bindings: fsl: scu: add scu key binding
From: Anson Huang @ 2019-09-17 3:12 UTC (permalink / raw)
To: robh+dt, mark.rutland, shawnguo, s.hauer, kernel, festevam,
catalin.marinas, will, dmitry.torokhov, aisheng.dong, ulf.hansson,
fugang.duan, peng.fan, leonard.crestez, daniel.baluta, olof,
mripard, arnd, jagan, dinguyen, bjorn.andersson,
marcin.juszkiewicz, andriy.shevchenko, yuehaibing, cw00.choi,
enric.balletbo, m.felsch, ping.bai, ronald, stefan, devicetree,
linux-kernel, linux-arm-kernel, linux-input
Cc: Linux-imx
NXP i.MX8QXP is an ARMv8 SoC with a Cortex-M4 core inside as
system controller, the system controller is in charge of system
power, clock and scu key event etc. management, Linux kernel has
to communicate with system controller via MU (message unit) IPC
to get scu key event, add binding doc for i.MX system controller
key driver.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
No changes.
---
.../devicetree/bindings/arm/freescale/fsl,scu.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
index c149fad..5eab7d0 100644
--- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
@@ -157,6 +157,15 @@ Required properties:
Optional properties:
- timeout-sec: contains the watchdog timeout in seconds.
+SCU key bindings based on SCU Message Protocol
+------------------------------------------------------------
+
+Required properties:
+- compatible: should be:
+ "fsl,imx8qxp-sc-key"
+ followed by "fsl,imx-sc-key";
+- linux,keycodes: See Documentation/devicetree/bindings/input/keys.txt
+
Example (imx8qxp):
-------------
aliases {
@@ -220,6 +229,11 @@ firmware {
compatible = "fsl,imx8qxp-sc-rtc";
};
+ scu_key: scu-key {
+ compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
+ linux,keycode = <KEY_POWER>;
+ };
+
watchdog {
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
timeout-sec = <60>;
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH RESEND V5 2/5] input: keyboard: imx_sc: Add i.MX system controller key support
From: Anson Huang @ 2019-09-17 3:12 UTC (permalink / raw)
To: robh+dt, mark.rutland, shawnguo, s.hauer, kernel, festevam,
catalin.marinas, will, dmitry.torokhov, aisheng.dong, ulf.hansson,
fugang.duan, peng.fan, leonard.crestez, daniel.baluta, olof,
mripard, arnd, jagan, dinguyen, bjorn.andersson,
marcin.juszkiewicz, andriy.shevchenko, yuehaibing, cw00.choi,
enric.balletbo, m.felsch, ping.bai, ronald, stefan, devicetree,
linux-kernel, linux-arm-kernel, linux-input
Cc: Linux-imx
In-Reply-To: <1568689939-8871-1-git-send-email-Anson.Huang@nxp.com>
i.MX8QXP is an ARMv8 SoC which has a Cortex-M4 system controller
inside, the system controller is in charge of controlling power,
clock and scu key etc..
Adds i.MX system controller key driver support, Linux kernel has
to communicate with system controller via MU (message unit) IPC
to get scu key's status.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
Changes since V4:
- reduce debounce time from 100mS to 30mS;
- remove unnecessary delay_check for button release interrupt which is NOT existing at all;
- using error instead of ret;
- move pm_wakeup_event() to interrupt notify and ONLY calling pm_relax() when button is released;
- remove unnecessary logic code of avoiding quick button press/release.
---
drivers/input/keyboard/Kconfig | 7 ++
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/imx_sc_key.c | 184 ++++++++++++++++++++++++++++++++++++
3 files changed, 192 insertions(+)
create mode 100644 drivers/input/keyboard/imx_sc_key.c
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 8911bc2..00f8428 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -469,6 +469,13 @@ config KEYBOARD_IMX
To compile this driver as a module, choose M here: the
module will be called imx_keypad.
+config KEYBOARD_IMX_SC_KEY
+ tristate "IMX SCU Key Driver"
+ depends on IMX_SCU
+ help
+ This is the system controller key driver for NXP i.MX SoCs with
+ system controller inside.
+
config KEYBOARD_NEWTON
tristate "Newton keyboard"
select SERIO
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 9510325..f5b1752 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
obj-$(CONFIG_KEYBOARD_IPAQ_MICRO) += ipaq-micro-keys.o
obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o
+obj-$(CONFIG_KEYBOARD_IMX_SC_KEY) += imx_sc_key.o
obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
diff --git a/drivers/input/keyboard/imx_sc_key.c b/drivers/input/keyboard/imx_sc_key.c
new file mode 100644
index 0000000..43485bd
--- /dev/null
+++ b/drivers/input/keyboard/imx_sc_key.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/firmware/imx/sci.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#define DEBOUNCE_TIME 30
+#define REPEAT_INTERVAL 60
+
+#define SC_IRQ_BUTTON 1
+#define SC_IRQ_GROUP_WAKE 3
+#define IMX_SC_MISC_FUNC_GET_BUTTON_STATUS 18
+
+struct imx_key_drv_data {
+ int keycode;
+ bool keystate; /* 1: pressed, 0: release */
+ struct delayed_work check_work;
+ struct input_dev *input;
+ struct imx_sc_ipc *key_ipc_handle;
+ struct notifier_block key_notifier;
+};
+
+struct imx_sc_msg_key {
+ struct imx_sc_rpc_msg hdr;
+ u8 state;
+};
+
+static int imx_sc_key_notify(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+ struct imx_key_drv_data *priv =
+ container_of(nb,
+ struct imx_key_drv_data,
+ key_notifier);
+
+ if ((event & SC_IRQ_BUTTON) && (*(u8 *)group == SC_IRQ_GROUP_WAKE)) {
+ schedule_delayed_work(&priv->check_work,
+ msecs_to_jiffies(DEBOUNCE_TIME));
+ pm_wakeup_event(priv->input->dev.parent, 0);
+ }
+
+ return 0;
+}
+
+static void imx_sc_check_for_events(struct work_struct *work)
+{
+ struct imx_key_drv_data *priv =
+ container_of(work,
+ struct imx_key_drv_data,
+ check_work.work);
+ struct input_dev *input = priv->input;
+ struct imx_sc_msg_key msg;
+ struct imx_sc_rpc_msg *hdr = &msg.hdr;
+ bool state;
+ int error;
+
+ hdr->ver = IMX_SC_RPC_VERSION;
+ hdr->svc = IMX_SC_RPC_SVC_MISC;
+ hdr->func = IMX_SC_MISC_FUNC_GET_BUTTON_STATUS;
+ hdr->size = 1;
+
+ error = imx_scu_call_rpc(priv->key_ipc_handle, &msg, true);
+ if (error) {
+ dev_err(&input->dev, "read imx sc key failed, error %d\n", error);
+ return;
+ }
+
+ state = (bool)msg.state;
+
+ if (state ^ priv->keystate) {
+ priv->keystate = state;
+ input_event(input, EV_KEY, priv->keycode, state);
+ input_sync(input);
+ if (!priv->keystate)
+ pm_relax(priv->input->dev.parent);
+ }
+
+ if (state)
+ schedule_delayed_work(&priv->check_work,
+ msecs_to_jiffies(REPEAT_INTERVAL));
+}
+
+static int imx_sc_key_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ static struct imx_key_drv_data *priv;
+ struct input_dev *input;
+ int error;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ error = imx_scu_get_handle(&priv->key_ipc_handle);
+ if (error)
+ return error;
+
+ if (of_property_read_u32(np, "linux,keycode", &priv->keycode)) {
+ dev_err(&pdev->dev, "missing KEY_POWER in DT\n");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&priv->check_work, imx_sc_check_for_events);
+
+ input = devm_input_allocate_device(&pdev->dev);
+ if (!input) {
+ dev_err(&pdev->dev, "failed to allocate the input device\n");
+ return -ENOMEM;
+ }
+
+ input->name = pdev->name;
+ input->phys = "imx-sc-key/input0";
+ input->id.bustype = BUS_HOST;
+
+ input_set_capability(input, EV_KEY, priv->keycode);
+
+ error = input_register_device(input);
+ if (error) {
+ dev_err(&pdev->dev, "failed to register input device\n");
+ return error;
+ }
+
+ priv->input = input;
+ platform_set_drvdata(pdev, priv);
+
+ error = imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, true);
+ if (error) {
+ dev_warn(&pdev->dev, "enable scu group irq failed\n");
+ return error;
+ }
+
+ priv->key_notifier.notifier_call = imx_sc_key_notify;
+ error = imx_scu_irq_register_notifier(&priv->key_notifier);
+ if (error) {
+ imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, false);
+ dev_warn(&pdev->dev, "register scu notifier failed\n");
+ return error;
+ }
+
+ return 0;
+}
+
+static int imx_sc_key_remove(struct platform_device *pdev)
+{
+ struct imx_key_drv_data *priv = platform_get_drvdata(pdev);
+
+ imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, false);
+ imx_scu_irq_unregister_notifier(&priv->key_notifier);
+ cancel_delayed_work_sync(&priv->check_work);
+
+ return 0;
+}
+
+static const struct of_device_id imx_sc_key_ids[] = {
+ { .compatible = "fsl,imx-sc-key" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_sc_key_ids);
+
+static struct platform_driver imx_sc_key_driver = {
+ .driver = {
+ .name = "imx-sc-key",
+ .of_match_table = imx_sc_key_ids,
+ },
+ .probe = imx_sc_key_probe,
+ .remove = imx_sc_key_remove,
+};
+module_platform_driver(imx_sc_key_driver);
+
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_DESCRIPTION("i.MX System Controller Key Driver");
+MODULE_LICENSE("GPL v2");
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH RESEND V5 3/5] arm64: dts: imx8qxp: Add scu key node
From: Anson Huang @ 2019-09-17 3:12 UTC (permalink / raw)
To: robh+dt, mark.rutland, shawnguo, s.hauer, kernel, festevam,
catalin.marinas, will, dmitry.torokhov, aisheng.dong, ulf.hansson,
fugang.duan, peng.fan, leonard.crestez, daniel.baluta, olof,
mripard, arnd, jagan, dinguyen, bjorn.andersson,
marcin.juszkiewicz, andriy.shevchenko, yuehaibing, cw00.choi,
enric.balletbo, m.felsch, ping.bai, ronald, stefan, devicetree,
linux-kernel, linux-arm-kernel, linux-input
Cc: Linux-imx
In-Reply-To: <1568689939-8871-1-git-send-email-Anson.Huang@nxp.com>
Add scu key node for i.MX8QXP, disabled by default as it
depends on board design.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
No changes.
---
arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 1133b41..71e38c1 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -8,6 +8,7 @@
#include <dt-bindings/clock/imx8-clock.h>
#include <dt-bindings/firmware/imx/rsrc.h>
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/pinctrl/pads-imx8qxp.h>
@@ -174,6 +175,12 @@
#power-domain-cells = <1>;
};
+ scu_key: scu-key {
+ compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
+ linux,keycode = <KEY_POWER>;
+ status = "disabled";
+ };
+
rtc: rtc {
compatible = "fsl,imx8qxp-sc-rtc";
};
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH RESEND V5 4/5] arm64: dts: imx8qxp-mek: Enable scu key
From: Anson Huang @ 2019-09-17 3:12 UTC (permalink / raw)
To: robh+dt, mark.rutland, shawnguo, s.hauer, kernel, festevam,
catalin.marinas, will, dmitry.torokhov, aisheng.dong, ulf.hansson,
fugang.duan, peng.fan, leonard.crestez, daniel.baluta, olof,
mripard, arnd, jagan, dinguyen, bjorn.andersson,
marcin.juszkiewicz, andriy.shevchenko, yuehaibing, cw00.choi,
enric.balletbo, m.felsch, ping.bai, ronald, stefan, devicetree,
linux-kernel, linux-arm-kernel, linux-input
Cc: Linux-imx
In-Reply-To: <1568689939-8871-1-git-send-email-Anson.Huang@nxp.com>
Enable scu key for i.MX8QXP MEK board.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
No changes.
---
arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 1946805..88dd9132 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -234,3 +234,7 @@
&adma_dsp {
status = "okay";
};
+
+&scu_key {
+ status = "okay";
+};
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH RESEND V5 5/5] arm64: defconfig: Enable CONFIG_KEYBOARD_IMX_SC_KEY as module
From: Anson Huang @ 2019-09-17 3:12 UTC (permalink / raw)
To: robh+dt, mark.rutland, shawnguo, s.hauer, kernel, festevam,
catalin.marinas, will, dmitry.torokhov, aisheng.dong, ulf.hansson,
fugang.duan, peng.fan, leonard.crestez, daniel.baluta, olof,
mripard, arnd, jagan, dinguyen, bjorn.andersson,
marcin.juszkiewicz, andriy.shevchenko, yuehaibing, cw00.choi,
enric.balletbo, m.felsch, ping.bai, ronald, stefan, devicetree,
linux-kernel, linux-arm-kernel, linux-input
Cc: Linux-imx
In-Reply-To: <1568689939-8871-1-git-send-email-Anson.Huang@nxp.com>
Select CONFIG_KEYBOARD_IMX_SC_KEY as module by default to
support i.MX8QXP scu key driver.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
No changes.
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0a70e10..9c83014 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -314,6 +314,7 @@ CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_ADC=m
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_SNVS_PWRKEY=m
+CONFIG_KEYBOARD_IMX_SC_KEY=m
CONFIG_KEYBOARD_CROS_EC=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* RE: [PATCH V5 1/5] dt-bindings: fsl: scu: add scu key binding
From: Anson Huang @ 2019-09-17 3:14 UTC (permalink / raw)
To: robh+dt@kernel.org, mark.rutland@arm.com, shawnguo@kernel.org,
s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com,
catalin.marinas@arm.com, will@kernel.org,
dmitry.torokhov@gmail.com, Aisheng Dong, ulf.hansson@linaro.org,
Andy Duan, Peng Fan, Leonard Crestez, Daniel Baluta,
olof@lixom.net, mripard@kernel.org, arnd@arndb.de,
jagan@amarulasolutions.com, dinguyen@kernel.org,
bjorn.andersson@linaro.org, marcin.juszkiewicz@linaro.org,
andriy.shevchenko@linux.intel.com, yuehaibing@huawei.com,
cw00.choi@samsung.com, enric.balletbo@collabora.com,
m.felsch@pengutronix.de, Jacky Bai, ronald@innovation.ch,
stefan@agner.ch, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-input@vger.kernel.org
Cc: dl-linux-imx
In-Reply-To: <1568688939-13649-1-git-send-email-Anson.Huang@nxp.com>
Sorry, please ignore this version, it has build issue, just resent the patch series.
Anson.
> Subject: [PATCH V5 1/5] dt-bindings: fsl: scu: add scu key binding
>
> NXP i.MX8QXP is an ARMv8 SoC with a Cortex-M4 core inside as system
> controller, the system controller is in charge of system power, clock and scu
> key event etc. management, Linux kernel has to communicate with system
> controller via MU (message unit) IPC to get scu key event, add binding doc for
> i.MX system controller key driver.
>
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> No changes.
> ---
> .../devicetree/bindings/arm/freescale/fsl,scu.txt | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> index c149fad..5eab7d0 100644
> --- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> @@ -157,6 +157,15 @@ Required properties:
> Optional properties:
> - timeout-sec: contains the watchdog timeout in seconds.
>
> +SCU key bindings based on SCU Message Protocol
> +------------------------------------------------------------
> +
> +Required properties:
> +- compatible: should be:
> + "fsl,imx8qxp-sc-key"
> + followed by "fsl,imx-sc-key";
> +- linux,keycodes: See Documentation/devicetree/bindings/input/keys.txt
> +
> Example (imx8qxp):
> -------------
> aliases {
> @@ -220,6 +229,11 @@ firmware {
> compatible = "fsl,imx8qxp-sc-rtc";
> };
>
> + scu_key: scu-key {
> + compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
> + linux,keycode = <KEY_POWER>;
> + };
> +
> watchdog {
> compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
> timeout-sec = <60>;
> --
> 2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH RFC 11/14] arm64: Move the ASID allocator code in a separate file
From: Anup Patel @ 2019-09-17 3:42 UTC (permalink / raw)
To: Will Deacon
Cc: julien.thierry@arm.com, catalin.marinas@arm.com, Palmer Dabbelt,
Will Deacon, christoffer.dall@arm.com, Atish Patra,
julien.grall@arm.com, guoren@kernel.org, gary@garyguo.net,
linux-riscv@lists.infradead.org, kvmarm@lists.cs.columbia.edu,
rppt@linux.ibm.com, Christoph Hellwig, aou@eecs.berkeley.edu,
Arnd Bergmann, suzuki.poulose@arm.com, marc.zyngier@arm.com,
Paul Walmsley, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org,
james.morse@arm.com
In-Reply-To: <20190916181800.7lfpt3t627byoomt@willie-the-truck>
> -----Original Message-----
> From: linux-kernel-owner@vger.kernel.org <linux-kernel-
> owner@vger.kernel.org> On Behalf Of Will Deacon
> Sent: Monday, September 16, 2019 11:48 PM
> To: Anup Patel <Anup.Patel@wdc.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>; guoren@kernel.org; Will Deacon
> <will.deacon@arm.com>; julien.thierry@arm.com; aou@eecs.berkeley.edu;
> james.morse@arm.com; Arnd Bergmann <arnd@arndb.de>;
> suzuki.poulose@arm.com; marc.zyngier@arm.com;
> catalin.marinas@arm.com; linux-kernel@vger.kernel.org;
> rppt@linux.ibm.com; Christoph Hellwig <hch@infradead.org>; Atish Patra
> <Atish.Patra@wdc.com>; julien.grall@arm.com; gary@garyguo.net; Paul
> Walmsley <paul.walmsley@sifive.com>; christoffer.dall@arm.com; linux-
> riscv@lists.infradead.org; kvmarm@lists.cs.columbia.edu; linux-arm-
> kernel@lists.infradead.org; iommu@lists.linux-foundation.org
> Subject: Re: [PATCH RFC 11/14] arm64: Move the ASID allocator code in a
> separate file
>
> On Sun, Sep 15, 2019 at 05:03:38AM +0000, Anup Patel wrote:
> >
> >
> > > -----Original Message-----
> > > From: linux-kernel-owner@vger.kernel.org <linux-kernel-
> > > owner@vger.kernel.org> On Behalf Of Palmer Dabbelt
> > > Sent: Saturday, September 14, 2019 7:31 PM
> > > To: will@kernel.org
> > > Cc: guoren@kernel.org; Will Deacon <will.deacon@arm.com>;
> > > julien.thierry@arm.com; aou@eecs.berkeley.edu;
> james.morse@arm.com;
> > > Arnd Bergmann <arnd@arndb.de>; suzuki.poulose@arm.com;
> > > marc.zyngier@arm.com; catalin.marinas@arm.com; Anup Patel
> > > <Anup.Patel@wdc.com>; linux-kernel@vger.kernel.org;
> > > rppt@linux.ibm.com; Christoph Hellwig <hch@infradead.org>; Atish
> > > Patra <Atish.Patra@wdc.com>; julien.grall@arm.com; gary@garyguo.net;
> > > Paul Walmsley <paul.walmsley@sifive.com>; christoffer.dall@arm.com;
> > > linux- riscv@lists.infradead.org; kvmarm@lists.cs.columbia.edu;
> > > linux-arm- kernel@lists.infradead.org;
> > > iommu@lists.linux-foundation.org
> > > Subject: Re: [PATCH RFC 11/14] arm64: Move the ASID allocator code
> > > in a separate file
> > >
> > > On Thu, 12 Sep 2019 07:02:56 PDT (-0700), will@kernel.org wrote:
> > > > On Sun, Sep 08, 2019 at 07:52:55AM +0800, Guo Ren wrote:
> > > >> On Mon, Jun 24, 2019 at 6:40 PM Will Deacon <will@kernel.org>
> wrote:
> > > >> > > I'll keep my system use the same ASID for SMP + IOMMU :P
> > > >> >
> > > >> > You will want a separate allocator for that:
> > > >> >
> > > >> > https://lkml.kernel.org/r/20190610184714.6786-2-jean-philippe.b
> > > >> > ruck
> > > >> > er@arm.com
> > > >>
> > > >> Yes, it is hard to maintain ASID between IOMMU and CPUMMU or
> > > >> different system, because it's difficult to synchronize the
> > > >> IO_ASID when the CPU ASID is rollover.
> > > >> But we could still use hardware broadcast TLB invalidation
> > > >> instruction to uniformly manage the ASID and IO_ASID, or
> > > >> OTHER_ASID in
> > > our IOMMU.
> > > >
> > > > That's probably a bad idea, because you'll likely stall execution
> > > > on the CPU until the IOTLB has completed invalidation. In the case
> > > > of ATS, I think an endpoint ATC is permitted to take over a minute
> > > > to respond. In reality, I suspect the worst you'll ever see would
> > > > be in the msec range, but that's still an unacceptable period of
> > > > time to hold a
> > > CPU.
> > > >
> > > >> Welcome to join our disscusion:
> > > >> "Introduce an implementation of IOMMU in linux-riscv"
> > > >> 9 Sep 2019, 10:45 Jade-room-I&II (Corinthia Hotel Lisbon) RISC-V
> > > >> MC
> > > >
> > > > I attended this session, but it unfortunately raised many more
> > > > questions than it answered.
> > >
> > > Ya, we're a long way from figuring this out.
> >
> > For everyone's reference, here is our first attempt at RISC-V ASID allocator:
> > http://archive.lwn.net:8080/linux-kernel/20190329045111.14040-1-anup.p
> > atel@wdc.com/T/#u
>
> With a reply stating that the patch "absolutely does not work" ;)
This patch was tested on existing HW (which does not have ASID implementation)
and tested on QEMU (which has very simplistic Implementation of ASID).
When I asked Gary Guo about way to get access to their HW (in same patch
email thread), I did not get any reply. After so many months passed, I now
doubt the his comment "absolutely does not work".
>
> What exactly do you want people to do with that? It's an awful lot of effort to
> review this sort of stuff and given that Guo Ren is talking about sharing page
> tables between the CPU and an accelerator, maybe you're better off
> stabilising Linux for the platforms that you can actually test rather than
> getting so far ahead of yourselves that you end up with a bunch of wasted
> work on patches that probably won't get merged any time soon.
The intention of the ASID patch was to encourage RISC-V implementations
having ASID in HW and also ensure that things don't break on existing HW.
I don't see our efforts being wasted in trying to make Linux RISC-V feature
complete and encouraging more feature rich RISC-V CPUs.
Delays in merging patches are fine as long as people have something to try
on their RISC-V CPU implementations.
>
> Seriously, they say "walk before you can run", but this is more "crawl before
> you can fly". What's the rush?
>
> Will
Regards,
Anup
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V5 2/5] input: keyboard: imx_sc: Add i.MX system controller key support
From: kbuild test robot @ 2019-09-17 3:42 UTC (permalink / raw)
To: Anson Huang
Cc: mark.rutland, ulf.hansson, ping.bai, catalin.marinas, peng.fan,
stefan, bjorn.andersson, leonard.crestez, will, festevam,
yuehaibing, marcin.juszkiewicz, cw00.choi, jagan, linux-input,
ronald, Linux-imx, devicetree, arnd, s.hauer, mripard, m.felsch,
enric.balletbo, robh+dt, andriy.shevchenko, daniel.baluta,
linux-arm-kernel, aisheng.dong, fugang.duan, dmitry.torokhov,
linux-kernel, dinguyen, kbuild-all, kernel, olof, shawnguo
In-Reply-To: <1568688939-13649-2-git-send-email-Anson.Huang@nxp.com>
[-- Attachment #1: Type: text/plain, Size: 4810 bytes --]
Hi Anson,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on linus/master]
[cannot apply to v5.3 next-20190916]
[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/Anson-Huang/dt-bindings-fsl-scu-add-scu-key-binding/20190917-105937
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=ia64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
In file included from drivers/input/keyboard/imx_sc_key.c:6:0:
drivers/input/keyboard/imx_sc_key.c: In function 'imx_sc_check_for_events':
>> drivers/input/keyboard/imx_sc_key.c:76:60: error: 'ret' undeclared (first use in this function); did you mean 'net'?
dev_err(&input->dev, "read imx sc key failed, ret %d\n", ret);
^
include/linux/device.h:1499:32: note: in definition of macro 'dev_err'
_dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__)
^~~~~~~~~~~
drivers/input/keyboard/imx_sc_key.c:76:60: note: each undeclared identifier is reported only once for each function it appears in
dev_err(&input->dev, "read imx sc key failed, ret %d\n", ret);
^
include/linux/device.h:1499:32: note: in definition of macro 'dev_err'
_dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__)
^~~~~~~~~~~
vim +76 drivers/input/keyboard/imx_sc_key.c
> 6 #include <linux/device.h>
7 #include <linux/err.h>
8 #include <linux/firmware/imx/sci.h>
9 #include <linux/init.h>
10 #include <linux/input.h>
11 #include <linux/interrupt.h>
12 #include <linux/jiffies.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/of_address.h>
17 #include <linux/platform_device.h>
18
19 #define DEBOUNCE_TIME 30
20 #define REPEAT_INTERVAL 60
21
22 #define SC_IRQ_BUTTON 1
23 #define SC_IRQ_GROUP_WAKE 3
24 #define IMX_SC_MISC_FUNC_GET_BUTTON_STATUS 18
25
26 struct imx_key_drv_data {
27 int keycode;
28 bool keystate; /* 1: pressed, 0: release */
29 struct delayed_work check_work;
30 struct input_dev *input;
31 struct imx_sc_ipc *key_ipc_handle;
32 struct notifier_block key_notifier;
33 };
34
35 struct imx_sc_msg_key {
36 struct imx_sc_rpc_msg hdr;
37 u8 state;
38 };
39
40 static int imx_sc_key_notify(struct notifier_block *nb,
41 unsigned long event, void *group)
42 {
43 struct imx_key_drv_data *priv =
44 container_of(nb,
45 struct imx_key_drv_data,
46 key_notifier);
47
48 if ((event & SC_IRQ_BUTTON) && (*(u8 *)group == SC_IRQ_GROUP_WAKE)) {
49 schedule_delayed_work(&priv->check_work,
50 msecs_to_jiffies(DEBOUNCE_TIME));
51 pm_wakeup_event(priv->input->dev.parent, 0);
52 }
53
54 return 0;
55 }
56
57 static void imx_sc_check_for_events(struct work_struct *work)
58 {
59 struct imx_key_drv_data *priv =
60 container_of(work,
61 struct imx_key_drv_data,
62 check_work.work);
63 struct input_dev *input = priv->input;
64 struct imx_sc_msg_key msg;
65 struct imx_sc_rpc_msg *hdr = &msg.hdr;
66 bool state;
67 int error;
68
69 hdr->ver = IMX_SC_RPC_VERSION;
70 hdr->svc = IMX_SC_RPC_SVC_MISC;
71 hdr->func = IMX_SC_MISC_FUNC_GET_BUTTON_STATUS;
72 hdr->size = 1;
73
74 error = imx_scu_call_rpc(priv->key_ipc_handle, &msg, true);
75 if (error) {
> 76 dev_err(&input->dev, "read imx sc key failed, ret %d\n", ret);
77 return;
78 }
79
80 state = (bool)msg.state;
81
82 if (state ^ priv->keystate) {
83 priv->keystate = state;
84 input_event(input, EV_KEY, priv->keycode, state);
85 input_sync(input);
86 if (!priv->keystate)
87 pm_relax(priv->input->dev.parent);
88 }
89
90 if (state)
91 schedule_delayed_work(&priv->check_work,
92 msecs_to_jiffies(REPEAT_INTERVAL));
93 }
94
---
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: 54623 bytes --]
[-- Attachment #3: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V7 3/3] arm64/mm: Enable memory hot remove
From: Anshuman Khandual @ 2019-09-17 4:36 UTC (permalink / raw)
To: Catalin Marinas
Cc: mark.rutland, mhocko, david, linux-mm, arunks, cpandya, ira.weiny,
will, steven.price, valentin.schneider, suzuki.poulose,
Robin.Murphy, broonie, cai, ard.biesheuvel, dan.j.williams,
linux-arm-kernel, osalvador, steve.capper, logang, linux-kernel,
akpm, mgorman
In-Reply-To: <20190913100955.GB55043@arrakis.emea.arm.com>
On 09/13/2019 03:39 PM, Catalin Marinas wrote:
> On Fri, Sep 13, 2019 at 11:28:01AM +0530, Anshuman Khandual wrote:
>> On 09/13/2019 01:45 AM, Catalin Marinas wrote:
>>> On Tue, Sep 03, 2019 at 03:15:58PM +0530, Anshuman Khandual wrote:
>>>> @@ -770,6 +1022,28 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
>>>> void vmemmap_free(unsigned long start, unsigned long end,
>>>> struct vmem_altmap *altmap)
>>>> {
>>>> +#ifdef CONFIG_MEMORY_HOTPLUG
>>>> + /*
>>>> + * FIXME: We should have called remove_pagetable(start, end, true).
>>>> + * vmemmap and vmalloc virtual range might share intermediate kernel
>>>> + * page table entries. Removing vmemmap range page table pages here
>>>> + * can potentially conflict with a concurrent vmalloc() allocation.
>>>> + *
>>>> + * This is primarily because vmalloc() does not take init_mm ptl for
>>>> + * the entire page table walk and it's modification. Instead it just
>>>> + * takes the lock while allocating and installing page table pages
>>>> + * via [p4d|pud|pmd|pte]_alloc(). A concurrently vanishing page table
>>>> + * entry via memory hot remove can cause vmalloc() kernel page table
>>>> + * walk pointers to be invalid on the fly which can cause corruption
>>>> + * or worst, a crash.
>>>> + *
>>>> + * So free_empty_tables() gets called where vmalloc and vmemmap range
>>>> + * do not overlap at any intermediate level kernel page table entry.
>>>> + */
>>>> + unmap_hotplug_range(start, end, true);
>>>> + if (!vmalloc_vmemmap_overlap)
>>>> + free_empty_tables(start, end);
>>>> +#endif
>>>> }
>>>
>>> So, I see the risk with overlapping and I guess for some kernel
>>> configurations (PAGE_SIZE == 64K) we may not be able to avoid it. If we
>>
>> Did not see 64K config options to have overlap, do you suspect they might ?
>> After the 52 bit KVA series has been merged, following configurations have
>> the vmalloc-vmemmap range overlap problem.
>>
>> - 4K page size with 48 bit VA space
>> - 16K page size with 48 bit VA space
>
> OK. I haven't checked, so it was just a guess that 64K has this problem
> since the pgd entry coverage is fairly large.
>
>>> can, that's great, otherwise could we rewrite the above functions to
>>> handle floor and ceiling similar to free_pgd_range()? (I wonder how this
>>> function works if you called it on init_mm and kernel address range). By
>>
>> Hmm, never tried that. Are you wondering if this can be used directly ?
>> There are two distinct elements which make it very specific to user page
>> tables, mmu_gather based TLB tracking and mm->pgtable_bytes accounting
>> with mm_dec_nr_pxx().
>
> Ah, I missed the mm_dec_nr_*(). So I don't think it would work directly.
> We could, however, use the same approach for kernel page tables.
Right.
>
>>> having the vmemmap start/end information it avoids freeing partially
>>> filled page table pages.
>>
>> Did you mean page table pages which can partially overlap with vmalloc ?
>
> Overlapping with the vmalloc range, not necessarily with a mapped
> vmalloc area.
>
>> The problem (race) is not because of the inability to deal with partially
>> filled table. We can handle that correctly as explained below [1]. The
>> problem is with inadequate kernel page table locking during vmalloc()
>> which might be accessing intermediate kernel page table pointers which is
>> being freed with free_empty_tables() concurrently. Hence we cannot free
>> any page table page which can ever have entries from vmalloc() range.
>
> The way you deal with the partially filled table in this patch is to
> avoid freeing if there is a non-empty entry (!p*d_none()). This is what
> causes the race with vmalloc. If you simply avoid freeing a pmd page,
> for example, if the range floor/ceiling is not aligned to PUD_SIZE,
> irrespective of whether the other entries are empty or not, you
> shouldn't have this problem. You do free the pte page if the range is
Right, the floor/ceiling alignment check should abort the process before
scanning for non-empty entries.
> aligned to PMD_SIZE but in this case it wouldn't overlap with the
> vmalloc space. That's how free_pgd_range() works.
Like free_pgd_range(), page table pages can be freed at lower levels when
they have the right alignment wrt floor/ceiling. I will change all existing
free_pxx_table() functions to accommodate floor/ceiling alignment checks to
achieve this.
>
> We may have some pgtable pages not freed at both ends of the range
> (maximum 6 in total) but I don't really see this an issue. They could be
> reused if something else gets mapped in that range.
I assume that the number 6 for maximum page possibility came from
(floor edge + ceiling edge) * (PTE table + PMD table + PUD table)
>
>> Though not completely sure, whether I really understood the suggestion above
>> with respect to the floor-ceiling mechanism as in free_pgd_range(). Are you
>> suggesting that we should only attempt to free up those vmemmap range page
>> table pages which *definitely* could never overlap with vmalloc by working
>> on a modified (i.e cut down with floor-ceiling while avoiding vmalloc range
>> at each level) vmemmap range instead ?
>
> You can ignore the overlap check altogether, only free the page tables
> with floor/ceiling set to the start/size passed to arch_remove_memory()
> and vmemmap_free().
Wondering if it will be better to use [VMEMMAP_START - VMEMMAP_END] and
[PAGE_OFFSET - PAGE_END] as floor/ceiling respectively with vmemmap_free()
and arch_remove_memory(). Not only it is safe to free all page table pages
which span over these maximum possible mapping range but also it reduces
the risk for alignment related wastage.
>
>> This can be one restrictive version of the function
>> free_empty_tables() called in case there is an overlap. So we will
>> maintain two versions for free_empty_tables(). Please correct me if
>> any the above assumptions or understanding is wrong.
>
> I'd rather have a single version of free_empty_tables(). As I said
> above, the only downside is that a partially filled pgtable page would
> not be freed even though the other entries are empty.
Sure. Also practically the limitation will be applicable only for vmemmap
mapping but not for linear mappings where the chances of overlap might be
negligible as it covers half kernel virtual address space.
>
>> But yes, with this we should be able to free up some possible empty page
>> table pages which were being left out in the current proposal when overlap
>> happens.
>>
>> [1] Skipping partially filled page tables
>>
>> All free_pXX_table() functions take care in avoiding freeing partially filled
>> page table pages whether they represent or ever represented linear or vmemmap
>> or vmalloc mapping in init_mm. They go over each individual entry in a given
>> page table making sure that each of them checks as pXX_none() before freeing
>> the entire page table page.
>
> Yes but that's what's causing the race with a vmalloc trying to create
> such entries.
free_pxx_table() needs to check for both floor-ceiling alignment before
making sure that the page table page is completely empty before freeing.
>
>>> Another question: could we do the page table and the actual vmemmap
>>> pages freeing in a single pass (sorry if this has been discussed
>>> before)?
>>
>> We could and some initial versions (till V5) of the series had that in fact.
>> Initially Mark Rutland had suggested to do this in two passes. Some extracts
>> from the previous discussion.
>>
>> https://lkml.org/lkml/2019/5/30/1159
>>
>> -----------------------
>> Looking at this some more, I don't think this is quite right, and tI
>> think that structure of the free_*() and remove_*() functions makes this
>> unnecessarily hard to follow. We should aim for this to be obviously
>> correct.
>>
>> The x86 code is the best template to follow here. As mentioned
>> previously, I'm fairly certain it's not entirely correct (e.g. due to
>> missing TLB maintenance), and we've already diverged a fair amount in
>> fixing up obvious issues, so we shouldn't aim to mirror it.
>>
>> I think that the structure of unmap_region() is closer to what we want
>> here -- do one pass to unmap leaf entries (and freeing the associated
>> memory if unmapping the vmemmap), then do a second pass cleaning up any
>> empty tables.
>> ----------------------
>>
>> Apart from the fact that two passes over the page table is cleaner and gives
>> us more granular and modular infrastructure to use for later purposes, it is
>> also a necessity in dealing with vmalloc-vmemmap overlap. free_empty_tables()
>> which is the second pass, can be skipped cleanly when overlap is detected.
>
> I'm fine with two passes for unmap and pgtable free for the time being
> and if they look fairly similar in a feature version, we can think of
> merging them. But for now, stick with two passes. The unmapping one in
> this patchset I think seems fine (though I haven't looked in detail).
Sure.
>
> There is also a race with ptdump that I haven't looked into.
The second patch in the series deals with that.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [v2, 2/3] arm: dts: ls1021a: fix that FlexTimer cannot wakeup system in deep sleep
From: Biwen Li @ 2019-09-17 4:41 UTC (permalink / raw)
To: leoyang.li, shawnguo, robh+dt, mark.rutland
Cc: devicetree, linuxppc-dev, linux-kernel, linux-arm-kernel,
Biwen Li
In-Reply-To: <20190917044119.21895-1-biwen.li@nxp.com>
The patch fix a bug that FlexTimer cannot
wakeup system in deep sleep.
Signed-off-by: Biwen Li <biwen.li@nxp.com>
---
Change in v2:
- None
arch/arm/boot/dts/ls1021a.dtsi | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index e3973b611c3a..377bb4717584 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -1000,12 +1000,13 @@
compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+";
reg = <0x0 0x1ee2140 0x0 0x8>;
#fsl,rcpm-wakeup-cells = <2>;
+ fsl,rcpm-scfg = <&scfg 0x0 0x51c>; /* SCFG_SPARECR8 */
};
ftm_alarm0: timer0@29d0000 {
compatible = "fsl,ls1021a-ftm-alarm";
reg = <0x0 0x29d0000 0x0 0x10000>;
- fsl,rcpm-wakeup = <&rcpm 0x0 0x20000000>;
+ fsl,rcpm-wakeup = <&rcpm 0x0 0x30000000>; /* FlexTimer1 and OCRAM1 are not powerdown during LPM20(sleep) */
interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
big-endian;
};
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [v2, 3/3] Documentation: dt: binding: fsl: Add 'fsl, rcpm-scfg' property
From: Biwen Li @ 2019-09-17 4:41 UTC (permalink / raw)
To: leoyang.li, shawnguo, robh+dt, mark.rutland
Cc: devicetree, linuxppc-dev, linux-kernel, linux-arm-kernel,
Biwen Li
In-Reply-To: <20190917044119.21895-1-biwen.li@nxp.com>
The 'fsl,rcpm-scfg' property is used to fix a bug
that FlexTimer cannot wakeup system in deep sleep on LS1021A
Signed-off-by: Biwen Li <biwen.li@nxp.com>
---
Change in v2:
- update desc of the property 'fsl,rcpm-scfg'
Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
index 5a33619d881d..f8dce247357a 100644
--- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
+++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
@@ -34,6 +34,11 @@ Chassis Version Example Chips
Optional properties:
- little-endian : RCPM register block is Little Endian. Without it RCPM
will be Big Endian (default case).
+ - fsl,rcpm-scfg : LS1021A has defect of failing to get data when
+ reading ippdexpcr. So add this property to help store one
+ copy to specified scfg_scrachpad_addr register for others
+ (such as U-Boot) reference. The first entry must be a link to the
+ SCFG device node, then followed by the offset of registers of SCFG.
Example:
The RCPM node for T4240:
@@ -43,6 +48,14 @@ The RCPM node for T4240:
#fsl,rcpm-wakeup-cells = <2>;
};
+The RCPM node for LS1021A:
+ rcpm: rcpm@1ee2140 {
+ compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+";
+ reg = <0x0 0x1ee2140 0x0 0x8>;
+ #fsl,rcpm-wakeup-cells = <2>;
+ fsl,rcpm-scfg = <&scfg 0x0 0x51c>; /* SCFG_SPARECR8 */
+ };
+
* Freescale RCPM Wakeup Source Device Tree Bindings
-------------------------------------------
Required fsl,rcpm-wakeup property should be added to a device node if the device
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [v2, 1/3] soc: fsl: fix that flextimer cannot wakeup system in deep sleep on LS1021A
From: Biwen Li @ 2019-09-17 4:41 UTC (permalink / raw)
To: leoyang.li, shawnguo, robh+dt, mark.rutland
Cc: devicetree, linuxppc-dev, linux-kernel, linux-arm-kernel,
Biwen Li
Why:
- Cannot write register RCPM_IPPDEXPCR1 on LS1021A,
Register RCPM_IPPDEXPCR1's default value is zero.
So the register value that reading from register
RCPM_IPPDEXPCR1 is always zero.
How:
- Save register RCPM_IPPDEXPCR1's value to
register SCFG_SPARECR8.(uboot's psci also
need reading value from the register SCFG_SPARECR8
to set register RCPM_IPPDEXPCR1)
Signed-off-by: Biwen Li <biwen.li@nxp.com>
---
Change in v2:
- fix stype problems
drivers/soc/fsl/rcpm.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c
index 82c0ad5e663e..0b710c24999c 100644
--- a/drivers/soc/fsl/rcpm.c
+++ b/drivers/soc/fsl/rcpm.c
@@ -13,6 +13,8 @@
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/kernel.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
#define RCPM_WAKEUP_CELL_MAX_SIZE 7
@@ -63,6 +65,31 @@ static int rcpm_pm_prepare(struct device *dev)
tmp |= value[i + 1];
iowrite32be(tmp, rcpm->ippdexpcr_base + i * 4);
}
+ #ifdef CONFIG_SOC_LS1021A
+ /* Workaround: There is a bug of register ippdexpcr1,
+ * cannot write it but can read it.Tt's default value is zero,
+ * then read it will always returns zero.
+ * So save ippdexpcr1's value to register SCFG_SPARECR8.
+ * And the value of ippdexpcr1 will be read from SCFG_SPARECR8.
+ */
+ {
+ struct regmap *rcpm_scfg_regmap = NULL;
+ u32 reg_offset[RCPM_WAKEUP_CELL_MAX_SIZE + 1];
+ u32 reg_value = 0;
+
+ rcpm_scfg_regmap = syscon_regmap_lookup_by_phandle(np, "fsl,rcpm-scfg");
+ if (rcpm_scfg_regmap) {
+ if (of_property_read_u32_array(dev->of_node,
+ "fsl,rcpm-scfg", reg_offset, rcpm->wakeup_cells + 1)) {
+ rcpm_scfg_regmap = NULL;
+ continue;
+ }
+ regmap_read(rcpm_scfg_regmap, reg_offset[i + 1], ®_value);
+ /* Write value to register SCFG_SPARECR8 */
+ regmap_write(rcpm_scfg_regmap, reg_offset[i + 1], tmp | reg_value);
+ }
+ }
+ #endif //CONFIG_SOC_LS1021A
}
}
} while (ws = wakeup_source_get_next(ws));
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v4 1/6] PM / devfreq: Don't take lock in devfreq_add_device
From: MyungJoo Ham @ 2019-09-17 5:01 UTC (permalink / raw)
To: leonard.crestez@nxp.com
Cc: Chanwoo Choi, linux-arm-kernel@lists.infradead.org,
linux-pm@vger.kernel.org
In-Reply-To: <CGME20190917050135epcms1p15ba77f52d2a34db0236fd81107dba07f@epcms1p1>
>A device usually doesn't need to lock itself during initialization
>because it is not yet reachable from other threads.
>
>This simplifies the code and helps avoid recursive lock warnings.
>
>Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
>---
From the line of
> err = device_register(&devfreq->dev);
Other threads may access the protected values.
Thus, if there are recursive lock warnings, we need to resolve it without eliminating lock usages.
--
MyungJoo Ham (함명주), Ph.D.
On-Device Lab, Platform Team, Samsung Research.
Cell: +82-10-6714-2858
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [v2,1/3] soc: fsl: fix that flextimer cannot wakeup system in deep sleep on LS1021A
From: Biwen Li @ 2019-09-17 5:18 UTC (permalink / raw)
To: Biwen Li, Leo Li, shawnguo@kernel.org, robh+dt@kernel.org,
mark.rutland@arm.com
Cc: devicetree@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190917044119.21895-1-biwen.li@nxp.com>
Hi all,
the linux patches depended by RCPM driver,FlexTimer driver and FlexTimer dts, need apply these patches as follows:
1. RCPM driver:
https://patchwork.kernel.org/series/162731/mbox/ (https://patchwork.kernel.org/patch/11105279/)
2. FlexTimer dts:
https://lore.kernel.org/patchwork/series/405653/mbox/ (https://lore.kernel.org/patchwork/patch/1112493/)
3. FlexTimer driver:
https://patchwork.ozlabs.org/series/124718/mbox/ (https://patchwork.ozlabs.org/patch/1145999/)
https://patchwork.ozlabs.org/series/126942/mbox/ (https://patchwork.ozlabs.org/patch/1152085/)
4. Adjust drivers/soc/fsl/Makefile:
remove the line 'obj-y += ftm_alarm.o' in drivers/soc/fsl/Makefile to resolve a compilation error
> Why:
> - Cannot write register RCPM_IPPDEXPCR1 on LS1021A,
> Register RCPM_IPPDEXPCR1's default value is zero.
> So the register value that reading from register
> RCPM_IPPDEXPCR1 is always zero.
>
> How:
> - Save register RCPM_IPPDEXPCR1's value to
> register SCFG_SPARECR8.(uboot's psci also
> need reading value from the register SCFG_SPARECR8
> to set register RCPM_IPPDEXPCR1)
>
> Signed-off-by: Biwen Li <biwen.li@nxp.com>
> ---
> Change in v2:
> - fix stype problems
>
> drivers/soc/fsl/rcpm.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index
> 82c0ad5e663e..0b710c24999c 100644
> --- a/drivers/soc/fsl/rcpm.c
> +++ b/drivers/soc/fsl/rcpm.c
> @@ -13,6 +13,8 @@
> #include <linux/slab.h>
> #include <linux/suspend.h>
> #include <linux/kernel.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
>
> #define RCPM_WAKEUP_CELL_MAX_SIZE 7
>
> @@ -63,6 +65,31 @@ static int rcpm_pm_prepare(struct device *dev)
> tmp |= value[i + 1];
> iowrite32be(tmp, rcpm->ippdexpcr_base + i * 4);
> }
> + #ifdef CONFIG_SOC_LS1021A
> + /* Workaround: There is a bug of register ippdexpcr1,
> + * cannot write it but can read it.Tt's default value is zero,
> + * then read it will always returns zero.
> + * So save ippdexpcr1's value to register SCFG_SPARECR8.
> + * And the value of ippdexpcr1 will be read from
> SCFG_SPARECR8.
> + */
> + {
> + struct regmap *rcpm_scfg_regmap = NULL;
> + u32 reg_offset[RCPM_WAKEUP_CELL_MAX_SIZE + 1];
> + u32 reg_value = 0;
> +
> + rcpm_scfg_regmap =
> syscon_regmap_lookup_by_phandle(np, "fsl,rcpm-scfg");
> + if (rcpm_scfg_regmap) {
> + if (of_property_read_u32_array(dev->of_node,
> + "fsl,rcpm-scfg", reg_offset,
> rcpm->wakeup_cells + 1)) {
> + rcpm_scfg_regmap = NULL;
> + continue;
> + }
> + regmap_read(rcpm_scfg_regmap, reg_offset[i + 1],
> ®_value);
> + /* Write value to register SCFG_SPARECR8 */
> + regmap_write(rcpm_scfg_regmap, reg_offset[i +
> 1], tmp | reg_value);
> + }
> + }
> + #endif //CONFIG_SOC_LS1021A
> }
> }
> } while (ws = wakeup_source_get_next(ws));
> --
> 2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] clk: at91: allow 24 Mhz clock as input for PLL
From: Eugen.Hristev @ 2019-09-17 5:59 UTC (permalink / raw)
To: sboyd, alexandre.belloni, linux-arm-kernel, linux-clk,
linux-kernel, mturquette
In-Reply-To: <20190916195246.CAE5C206C2@mail.kernel.org>
On 16.09.2019 22:52, Stephen Boyd wrote:
> Quoting Eugen.Hristev@microchip.com (2019-09-10 23:39:20)
>> From: Eugen Hristev <eugen.hristev@microchip.com>
>>
>> The PLL input range needs to be able to allow 24 Mhz crystal as input
>> Update the range accordingly in plla characteristics struct
>>
>> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
>> ---
>
> Is there a Fixes: tag for this? Seems like it was always wrong?
>
Hi Stephen,
At the initial design , the 12 Mhz was the only possibility for the
boards themselves. But, with the commit who added this:
Fixes: c561e41ce4d2 ("clk: at91: add sama5d2 PMC driver")
Eugen
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH 03/15] spi: make `cs_change_delay` the first user of the `spi_delay` logic
From: Ardelean, Alexandru @ 2019-09-17 6:05 UTC (permalink / raw)
To: broonie@kernel.org
Cc: f.fainelli@gmail.com, baolin.wang@linaro.org,
linux-iio@vger.kernel.org, zhang.lyra@gmail.com,
linus.walleij@linaro.org, linux-kernel@vger.kernel.org,
linux-spi@vger.kernel.org, bcm-kernel-feedback-list@broadcom.com,
linux-arm-kernel@lists.infradead.org, linux-tegra@vger.kernel.org,
orsonzhai@gmail.com, jic23@kernel.org
In-Reply-To: <20190916134309.GH4352@sirena.co.uk>
On Mon, 2019-09-16 at 14:43 +0100, Mark Brown wrote:
> [External]
>
> On Mon, Sep 16, 2019 at 01:04:42PM +0000, Ardelean, Alexandru wrote:
> > On Mon, 2019-09-16 at 13:47 +0100, Mark Brown wrote:
> > > That v3 seems to be a small subset of this series?
> > Ack.
> > V3 is the first 4 patches from this series.
> > Well, patches 3 & 4 are squashed.
> > I am 100% convinced that the entire series is a good idea.
Something happened here to the "not" word.
Probably got lost in an alternate dimension ¯\_(ツ)_/¯ .
Was supposed to be:
"I am not 100% convinced that the entire series is a good idea."
> > In the sense that a `struct spi_delay` may be a good idea, but at the
> > same time, it may be un-needed.
> > All I wanted to do, was to add another delay somewhere, and got lost in
> > the rework of current delays.
> > I thought about proposing just the first 4 patches [on their own], but
> > I thought that showing the current series as-is
> > now, may be a good idea as well [to gather some feedback].
>
> I think it makes more sense to review as a whole series rather than only
> a part of the conversion, it doesn't really help to only do part of it.
>
> Please fix your mail client to word wrap within paragraphs at something
> substantially less than 80 columns. Doing this makes your messages much
> easier to read and reply to.
Ack.
Problem is: I have to re-setup my email client every now-n-then since the
work-email server has some issues with Linux email clients.
And I sometimes forget to configure this.
[ Exchange does not always get along well with non-Outlook clients ]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 0/3] pinctrl: meson-a1: add pinctrl driver
From: Qianggui Song @ 2019-09-17 6:07 UTC (permalink / raw)
To: Linus Walleij, linux-gpio
Cc: Qianggui Song, Mark Rutland, Hanjie Lin, Jianxin Pan,
Neil Armstrong, Martin Blumenstingl, Kevin Hilman, linux-kernel,
devicetree, Rob Herring, linux-arm-kernel, Carlo Caione,
linux-amlogic, Xingyu Chen, Jerome Brunet
This patchset adds Pin controller driver support for Meson-A1 Soc
which shares the same register layout of pinmux with previous
Meson-G12A, however there is difference for gpio and pin config
registers in A1.
This patchset is based on A1 DTBv4[1].
[1] https://lore.kernel.org/linux-amlogic/1568276370-54181-1-git-send-email-jianxin.pan@amlogic.com
Qianggui Song (3):
pinctrl: add compatible for Amlogic Meson A1 pin controller
pinctrl: meson-a1: add pinctrl driver for Meson A1 Soc
arm64: dts: meson: a1: add pinctrl controller support
.../devicetree/bindings/pinctrl/meson,pinctrl.txt | 1 +
arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 18 +
drivers/pinctrl/meson/Kconfig | 6 +
drivers/pinctrl/meson/Makefile | 1 +
drivers/pinctrl/meson/pinctrl-meson-a1.c | 942 +++++++++++++++++++++
drivers/pinctrl/meson/pinctrl-meson.c | 8 +-
drivers/pinctrl/meson/pinctrl-meson.h | 9 +
include/dt-bindings/gpio/meson-a1-gpio.h | 73 ++
8 files changed, 1056 insertions(+), 2 deletions(-)
create mode 100644 drivers/pinctrl/meson/pinctrl-meson-a1.c
create mode 100644 include/dt-bindings/gpio/meson-a1-gpio.h
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 1/3] pinctrl: add compatible for Amlogic Meson A1 pin controller
From: Qianggui Song @ 2019-09-17 6:07 UTC (permalink / raw)
To: Linus Walleij, linux-gpio
Cc: Qianggui Song, Mark Rutland, Hanjie Lin, Jianxin Pan,
Neil Armstrong, Martin Blumenstingl, Kevin Hilman, linux-kernel,
devicetree, Rob Herring, linux-arm-kernel, Carlo Caione,
linux-amlogic, Xingyu Chen, Jerome Brunet
In-Reply-To: <1568700442-18540-1-git-send-email-qianggui.song@amlogic.com>
Add new compatible name for Amlogic's Meson-A1 pin controller
add a dt-binding header file which document the detail pin names.
Signed-off-by: Qianggui Song <qianggui.song@amlogic.com>
Signed-off-by: Xingyu Chen <xingyu.chen@amlogic.com>
Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com>
---
.../devicetree/bindings/pinctrl/meson,pinctrl.txt | 1 +
include/dt-bindings/gpio/meson-a1-gpio.h | 73 ++++++++++++++++++++++
2 files changed, 74 insertions(+)
create mode 100644 include/dt-bindings/gpio/meson-a1-gpio.h
diff --git a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
index 10dc4f7..0aff1f2 100644
--- a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
@@ -15,6 +15,7 @@ Required properties for the root node:
"amlogic,meson-axg-aobus-pinctrl"
"amlogic,meson-g12a-periphs-pinctrl"
"amlogic,meson-g12a-aobus-pinctrl"
+ "amlogic,meson-a1-periphs-pinctrl"
- reg: address and size of registers controlling irq functionality
=== GPIO sub-nodes ===
diff --git a/include/dt-bindings/gpio/meson-a1-gpio.h b/include/dt-bindings/gpio/meson-a1-gpio.h
new file mode 100644
index 0000000..40e57a5
--- /dev/null
+++ b/include/dt-bindings/gpio/meson-a1-gpio.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Qianggui Song <qianggui.song@amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_MESON_A1_GPIO_H
+#define _DT_BINDINGS_MESON_A1_GPIO_H
+
+#define GPIOP_0 0
+#define GPIOP_1 1
+#define GPIOP_2 2
+#define GPIOP_3 3
+#define GPIOP_4 4
+#define GPIOP_5 5
+#define GPIOP_6 6
+#define GPIOP_7 7
+#define GPIOP_8 8
+#define GPIOP_9 9
+#define GPIOP_10 10
+#define GPIOP_11 11
+#define GPIOP_12 12
+#define GPIOB_0 13
+#define GPIOB_1 14
+#define GPIOB_2 15
+#define GPIOB_3 16
+#define GPIOB_4 17
+#define GPIOB_5 18
+#define GPIOB_6 19
+#define GPIOX_0 20
+#define GPIOX_1 21
+#define GPIOX_2 22
+#define GPIOX_3 23
+#define GPIOX_4 24
+#define GPIOX_5 25
+#define GPIOX_6 26
+#define GPIOX_7 27
+#define GPIOX_8 28
+#define GPIOX_9 29
+#define GPIOX_10 30
+#define GPIOX_11 31
+#define GPIOX_12 32
+#define GPIOX_13 33
+#define GPIOX_14 34
+#define GPIOX_15 35
+#define GPIOX_16 36
+#define GPIOF_0 37
+#define GPIOF_1 38
+#define GPIOF_2 39
+#define GPIOF_3 40
+#define GPIOF_4 41
+#define GPIOF_5 42
+#define GPIOF_6 43
+#define GPIOF_7 44
+#define GPIOF_8 45
+#define GPIOF_9 46
+#define GPIOF_10 47
+#define GPIOF_11 48
+#define GPIOF_12 49
+#define GPIOA_0 50
+#define GPIOA_1 51
+#define GPIOA_2 52
+#define GPIOA_3 53
+#define GPIOA_4 54
+#define GPIOA_5 55
+#define GPIOA_6 56
+#define GPIOA_7 57
+#define GPIOA_8 58
+#define GPIOA_9 59
+#define GPIOA_10 60
+#define GPIOA_11 61
+
+#endif /* _DT_BINDINGS_MESON_A1_GPIO_H */
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 2/3] pinctrl: meson-a1: add pinctrl driver for Meson A1 Soc
From: Qianggui Song @ 2019-09-17 6:07 UTC (permalink / raw)
To: Linus Walleij, linux-gpio
Cc: Qianggui Song, Mark Rutland, Hanjie Lin, Jianxin Pan,
Neil Armstrong, Martin Blumenstingl, Kevin Hilman, linux-kernel,
Rob Herring, linux-arm-kernel, Carlo Caione, linux-amlogic,
Xingyu Chen, Jerome Brunet
In-Reply-To: <1568700442-18540-1-git-send-email-qianggui.song@amlogic.com>
Add pinctrl driver for Meson A1 Soc which share the same register layout of
pinmux with previous Meson-G12A, however there is difference for gpio
and pin config register in A1. The register layout is as below:
/* first bank */ /* addr */
- P_PADCTRL_GPIOP_I base + 0x00 << 2
- P_PADCTRL_GPIOP_O base + 0x01 << 2
- P_PADCTRL_GPIOP_OEN base + 0x02 << 2
- P_PADCTRL_GPIOP_PULL_EN base + 0x03 << 2
- P_PADCTRL_GPIOP_PULL_UP base + 0x04 << 2
- P_PADCTRL_GPIOP_DS base + 0x05 << 2
/* second bank */
- P_PADCTRL_GPIOB_I base + 0x10 << 2
- P_PADCTRL_GPIOB_O base + 0x11 << 2
- P_PADCTRL_GPIOB_OEN base + 0x12 << 2
- P_PADCTRL_GPIOB_PULL_EN base + 0x13 << 2
- P_PADCTRL_GPIOB_PULL_UP base + 0x14 << 2
- P_PADCTRL_GPIOB_DS base + 0x15 << 2
Each bank contains at least 6 registers to be configured, if one bank has
more than 16 gpios, an extra P_PADCTRL_GPIO[X]_DS_EXT is included. Between
two adjacent P_PADCTRL_GPIO[X]_I, there is an offset 0x10, that is to say,
for third bank, the offsets will be 0x20,0x21,0x22,0x23,0x24,0x25 according
to above register layout.
Current Meson pinctrl driver can cover such change by using base address of
GPIO as that of drive-strength. While simply giving reg_ds = reg_pullen
make wrong value to reg_ds for Soc that not support drive-strength like AXG
. Here a private data used to identify register layout is introduced.
Signed-off-by: Qianggui Song <qianggui.song@amlogic.com>
Signed-off-by: Xingyu Chen <xingyu.chen@amlogic.com>
Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com>
---
drivers/pinctrl/meson/Kconfig | 6 +
drivers/pinctrl/meson/Makefile | 1 +
drivers/pinctrl/meson/pinctrl-meson-a1.c | 942 +++++++++++++++++++++++++++++++
drivers/pinctrl/meson/pinctrl-meson.c | 8 +-
drivers/pinctrl/meson/pinctrl-meson.h | 9 +
5 files changed, 964 insertions(+), 2 deletions(-)
create mode 100644 drivers/pinctrl/meson/pinctrl-meson-a1.c
diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig
index df55f61..3cb1191 100644
--- a/drivers/pinctrl/meson/Kconfig
+++ b/drivers/pinctrl/meson/Kconfig
@@ -54,4 +54,10 @@ config PINCTRL_MESON_G12A
select PINCTRL_MESON_AXG_PMX
default y
+config PINCTRL_MESON_A1
+ bool "Meson a1 Soc pinctrl driver"
+ depends on ARM64
+ select PINCTRL_MESON_AXG_PMX
+ default y
+
endif
diff --git a/drivers/pinctrl/meson/Makefile b/drivers/pinctrl/meson/Makefile
index a69c565..1a5bffe 100644
--- a/drivers/pinctrl/meson/Makefile
+++ b/drivers/pinctrl/meson/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_PINCTRL_MESON_GXL) += pinctrl-meson-gxl.o
obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o
obj-$(CONFIG_PINCTRL_MESON_AXG) += pinctrl-meson-axg.o
obj-$(CONFIG_PINCTRL_MESON_G12A) += pinctrl-meson-g12a.o
+obj-$(CONFIG_PINCTRL_MESON_A1) += pinctrl-meson-a1.o
diff --git a/drivers/pinctrl/meson/pinctrl-meson-a1.c b/drivers/pinctrl/meson/pinctrl-meson-a1.c
new file mode 100644
index 0000000..f3a88f1
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-a1.c
@@ -0,0 +1,942 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Pin controller and GPIO driver for Amlogic Meson A1 SoC.
+ *
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Qianggui Song <qianggui.song@amlogic.com>
+ */
+
+#include <dt-bindings/gpio/meson-a1-gpio.h>
+#include "pinctrl-meson.h"
+#include "pinctrl-meson-axg-pmx.h"
+
+static const struct pinctrl_pin_desc meson_a1_periphs_pins[] = {
+ MESON_PIN(GPIOP_0),
+ MESON_PIN(GPIOP_1),
+ MESON_PIN(GPIOP_2),
+ MESON_PIN(GPIOP_3),
+ MESON_PIN(GPIOP_4),
+ MESON_PIN(GPIOP_5),
+ MESON_PIN(GPIOP_6),
+ MESON_PIN(GPIOP_7),
+ MESON_PIN(GPIOP_8),
+ MESON_PIN(GPIOP_9),
+ MESON_PIN(GPIOP_10),
+ MESON_PIN(GPIOP_11),
+ MESON_PIN(GPIOP_12),
+ MESON_PIN(GPIOB_0),
+ MESON_PIN(GPIOB_1),
+ MESON_PIN(GPIOB_2),
+ MESON_PIN(GPIOB_3),
+ MESON_PIN(GPIOB_4),
+ MESON_PIN(GPIOB_5),
+ MESON_PIN(GPIOB_6),
+ MESON_PIN(GPIOX_0),
+ MESON_PIN(GPIOX_1),
+ MESON_PIN(GPIOX_2),
+ MESON_PIN(GPIOX_3),
+ MESON_PIN(GPIOX_4),
+ MESON_PIN(GPIOX_5),
+ MESON_PIN(GPIOX_6),
+ MESON_PIN(GPIOX_7),
+ MESON_PIN(GPIOX_8),
+ MESON_PIN(GPIOX_9),
+ MESON_PIN(GPIOX_10),
+ MESON_PIN(GPIOX_11),
+ MESON_PIN(GPIOX_12),
+ MESON_PIN(GPIOX_13),
+ MESON_PIN(GPIOX_14),
+ MESON_PIN(GPIOX_15),
+ MESON_PIN(GPIOX_16),
+ MESON_PIN(GPIOF_0),
+ MESON_PIN(GPIOF_1),
+ MESON_PIN(GPIOF_2),
+ MESON_PIN(GPIOF_3),
+ MESON_PIN(GPIOF_4),
+ MESON_PIN(GPIOF_5),
+ MESON_PIN(GPIOF_6),
+ MESON_PIN(GPIOF_7),
+ MESON_PIN(GPIOF_8),
+ MESON_PIN(GPIOF_9),
+ MESON_PIN(GPIOF_10),
+ MESON_PIN(GPIOF_11),
+ MESON_PIN(GPIOF_12),
+ MESON_PIN(GPIOA_0),
+ MESON_PIN(GPIOA_1),
+ MESON_PIN(GPIOA_2),
+ MESON_PIN(GPIOA_3),
+ MESON_PIN(GPIOA_4),
+ MESON_PIN(GPIOA_5),
+ MESON_PIN(GPIOA_6),
+ MESON_PIN(GPIOA_7),
+ MESON_PIN(GPIOA_8),
+ MESON_PIN(GPIOA_9),
+ MESON_PIN(GPIOA_10),
+ MESON_PIN(GPIOA_11),
+};
+
+/* psram */
+static const unsigned int psram_clkn_pins[] = { GPIOP_0 };
+static const unsigned int psram_clkp_pins[] = { GPIOP_1 };
+static const unsigned int psram_ce_n_pins[] = { GPIOP_2 };
+static const unsigned int psram_rst_n_pins[] = { GPIOP_3 };
+static const unsigned int psram_adq0_pins[] = { GPIOP_4 };
+static const unsigned int psram_adq1_pins[] = { GPIOP_5 };
+static const unsigned int psram_adq2_pins[] = { GPIOP_6 };
+static const unsigned int psram_adq3_pins[] = { GPIOP_7 };
+static const unsigned int psram_adq4_pins[] = { GPIOP_8 };
+static const unsigned int psram_adq5_pins[] = { GPIOP_9 };
+static const unsigned int psram_adq6_pins[] = { GPIOP_10 };
+static const unsigned int psram_adq7_pins[] = { GPIOP_11 };
+static const unsigned int psram_dqs_dm_pins[] = { GPIOP_12 };
+
+/* sdcard */
+static const unsigned int sdcard_d0_b_pins[] = { GPIOB_0 };
+static const unsigned int sdcard_d1_b_pins[] = { GPIOB_1 };
+static const unsigned int sdcard_d2_b_pins[] = { GPIOB_2 };
+static const unsigned int sdcard_d3_b_pins[] = { GPIOB_3 };
+static const unsigned int sdcard_clk_b_pins[] = { GPIOB_4 };
+static const unsigned int sdcard_cmd_b_pins[] = { GPIOB_5 };
+
+static const unsigned int sdcard_d0_x_pins[] = { GPIOX_0 };
+static const unsigned int sdcard_d1_x_pins[] = { GPIOX_1 };
+static const unsigned int sdcard_d2_x_pins[] = { GPIOX_2 };
+static const unsigned int sdcard_d3_x_pins[] = { GPIOX_3 };
+static const unsigned int sdcard_clk_x_pins[] = { GPIOX_4 };
+static const unsigned int sdcard_cmd_x_pins[] = { GPIOX_5 };
+
+/* spif */
+static const unsigned int spif_mo_pins[] = { GPIOB_0 };
+static const unsigned int spif_mi_pins[] = { GPIOB_1 };
+static const unsigned int spif_wp_n_pins[] = { GPIOB_2 };
+static const unsigned int spif_hold_n_pins[] = { GPIOB_3 };
+static const unsigned int spif_clk_pins[] = { GPIOB_4 };
+static const unsigned int spif_cs_pins[] = { GPIOB_5 };
+
+/* i2c0 */
+static const unsigned int i2c0_sck_f9_pins[] = { GPIOF_9 };
+static const unsigned int i2c0_sda_f10_pins[] = { GPIOF_10 };
+static const unsigned int i2c0_sck_f11_pins[] = { GPIOF_11 };
+static const unsigned int i2c0_sda_f12_pins[] = { GPIOF_12 };
+
+/* i2c1 */
+static const unsigned int i2c1_sda_x_pins[] = { GPIOX_9 };
+static const unsigned int i2c1_sck_x_pins[] = { GPIOX_10 };
+static const unsigned int i2c1_sda_a_pins[] = { GPIOA_10 };
+static const unsigned int i2c1_sck_a_pins[] = { GPIOA_11 };
+
+/* i2c2 */
+static const unsigned int i2c2_sck_x0_pins[] = { GPIOX_0 };
+static const unsigned int i2c2_sda_x1_pins[] = { GPIOX_1 };
+static const unsigned int i2c2_sck_x15_pins[] = { GPIOX_15 };
+static const unsigned int i2c2_sda_x16_pins[] = { GPIOX_16 };
+static const unsigned int i2c2_sck_a4_pins[] = { GPIOA_4 };
+static const unsigned int i2c2_sda_a5_pins[] = { GPIOA_5 };
+static const unsigned int i2c2_sck_a8_pins[] = { GPIOA_8 };
+static const unsigned int i2c2_sda_a9_pins[] = { GPIOA_9 };
+
+/* i2c3 */
+static const unsigned int i2c3_sck_f_pins[] = { GPIOF_4 };
+static const unsigned int i2c3_sda_f_pins[] = { GPIOF_5 };
+static const unsigned int i2c3_sck_x_pins[] = { GPIOX_11 };
+static const unsigned int i2c3_sda_x_pins[] = { GPIOX_12 };
+
+/* i2c slave */
+static const unsigned int i2c_slave_sck_a_pins[] = { GPIOA_10 };
+static const unsigned int i2c_slave_sda_a_pins[] = { GPIOA_11 };
+static const unsigned int i2c_slave_sck_f_pins[] = { GPIOF_11 };
+static const unsigned int i2c_slave_sda_f_pins[] = { GPIOF_12 };
+
+/* uart_a */
+static const unsigned int uart_a_tx_pins[] = { GPIOX_11 };
+static const unsigned int uart_a_rx_pins[] = { GPIOX_12 };
+static const unsigned int uart_a_cts_pins[] = { GPIOX_13 };
+static const unsigned int uart_a_rts_pins[] = { GPIOX_14 };
+
+/* uart_b */
+static const unsigned int uart_b_tx_x_pins[] = { GPIOX_7 };
+static const unsigned int uart_b_rx_x_pins[] = { GPIOX_8 };
+static const unsigned int uart_b_tx_f_pins[] = { GPIOF_0 };
+static const unsigned int uart_b_rx_f_pins[] = { GPIOF_1 };
+
+/* uart_c */
+static const unsigned int uart_c_tx_x0_pins[] = { GPIOX_0 };
+static const unsigned int uart_c_rx_x1_pins[] = { GPIOX_1 };
+static const unsigned int uart_c_cts_pins[] = { GPIOX_2 };
+static const unsigned int uart_c_rts_pins[] = { GPIOX_3 };
+static const unsigned int uart_c_tx_x15_pins[] = { GPIOX_15 };
+static const unsigned int uart_c_rx_x16_pins[] = { GPIOX_16 };
+
+/* pmw_a */
+static const unsigned int pwm_a_x6_pins[] = { GPIOX_6 };
+static const unsigned int pwm_a_x7_pins[] = { GPIOX_7 };
+static const unsigned int pwm_a_f6_pins[] = { GPIOF_6 };
+static const unsigned int pwm_a_f10_pins[] = { GPIOF_10 };
+static const unsigned int pwm_a_a_pins[] = { GPIOA_5 };
+
+/* pmw_b */
+static const unsigned int pwm_b_x_pins[] = { GPIOX_8 };
+static const unsigned int pwm_b_f_pins[] = { GPIOF_7 };
+static const unsigned int pwm_b_a_pins[] = { GPIOA_11 };
+
+/* pmw_c */
+static const unsigned int pwm_c_x_pins[] = { GPIOX_9 };
+static const unsigned int pwm_c_f3_pins[] = { GPIOF_3 };
+static const unsigned int pwm_c_f8_pins[] = { GPIOF_8 };
+static const unsigned int pwm_c_a_pins[] = { GPIOA_10 };
+
+/* pwm_d */
+static const unsigned int pwm_d_x10_pins[] = { GPIOX_10 };
+static const unsigned int pwm_d_x13_pins[] = { GPIOX_13 };
+static const unsigned int pwm_d_x15_pins[] = { GPIOX_15 };
+static const unsigned int pwm_d_f_pins[] = { GPIOF_11 };
+
+/* pwm_e */
+static const unsigned int pwm_e_p_pins[] = { GPIOP_3 };
+static const unsigned int pwm_e_x2_pins[] = { GPIOX_2 };
+static const unsigned int pwm_e_x14_pins[] = { GPIOX_14 };
+static const unsigned int pwm_e_x16_pins[] = { GPIOX_16 };
+static const unsigned int pwm_e_f_pins[] = { GPIOF_3 };
+static const unsigned int pwm_e_a_pins[] = { GPIOA_0 };
+
+/* pwm_f */
+static const unsigned int pwm_f_b_pins[] = { GPIOB_6 };
+static const unsigned int pwm_f_x_pins[] = { GPIOX_3 };
+static const unsigned int pwm_f_f4_pins[] = { GPIOF_4 };
+static const unsigned int pwm_f_f12_pins[] = { GPIOF_12 };
+
+/* pwm_a_hiz */
+static const unsigned int pwm_a_hiz_f8_pins[] = { GPIOF_8 };
+static const unsigned int pwm_a_hiz_f10_pins[] = { GPIOF_10 };
+static const unsigned int pmw_a_hiz_f6_pins[] = { GPIOF_6 };
+
+/* pwm_b_hiz */
+static const unsigned int pwm_b_hiz_pins[] = { GPIOF_7 };
+
+/* pmw_c_hiz */
+static const unsigned int pwm_c_hiz_pins[] = { GPIOF_8 };
+
+/* tdm_a */
+static const unsigned int tdm_a_dout1_pins[] = { GPIOX_7 };
+static const unsigned int tdm_a_dout0_pins[] = { GPIOX_8 };
+static const unsigned int tdm_a_fs_pins[] = { GPIOX_9 };
+static const unsigned int tdm_a_sclk_pins[] = { GPIOX_10 };
+static const unsigned int tdm_a_din1_pins[] = { GPIOX_7 };
+static const unsigned int tdm_a_din0_pins[] = { GPIOX_8 };
+static const unsigned int tdm_a_slv_fs_pins[] = { GPIOX_9 };
+static const unsigned int tdm_a_slv_sclk_pins[] = { GPIOX_10 };
+
+/* spi_a */
+static const unsigned int spi_a_mosi_x2_pins[] = { GPIOX_2 };
+static const unsigned int spi_a_ss0_x3_pins[] = { GPIOX_3 };
+static const unsigned int spi_a_sclk_x4_pins[] = { GPIOX_4 };
+static const unsigned int spi_a_miso_x5_pins[] = { GPIOX_5 };
+static const unsigned int spi_a_mosi_x7_pins[] = { GPIOX_7 };
+static const unsigned int spi_a_miso_x8_pins[] = { GPIOX_8 };
+static const unsigned int spi_a_ss0_x9_pins[] = { GPIOX_9 };
+static const unsigned int spi_a_sclk_x10_pins[] = { GPIOX_10 };
+
+static const unsigned int spi_a_mosi_a_pins[] = { GPIOA_6 };
+static const unsigned int spi_a_miso_a_pins[] = { GPIOA_7 };
+static const unsigned int spi_a_ss0_a_pins[] = { GPIOA_8 };
+static const unsigned int spi_a_sclk_a_pins[] = { GPIOA_9 };
+
+/* pdm */
+static const unsigned int pdm_din0_x_pins[] = { GPIOX_7 };
+static const unsigned int pdm_din1_x_pins[] = { GPIOX_8 };
+static const unsigned int pdm_din2_x_pins[] = { GPIOX_9 };
+static const unsigned int pdm_dclk_x_pins[] = { GPIOX_10 };
+
+static const unsigned int pdm_din2_a_pins[] = { GPIOA_6 };
+static const unsigned int pdm_din1_a_pins[] = { GPIOA_7 };
+static const unsigned int pdm_din0_a_pins[] = { GPIOA_8 };
+static const unsigned int pdm_dclk_pins[] = { GPIOA_9 };
+
+/* gen_clk */
+static const unsigned int gen_clk_x_pins[] = { GPIOX_7 };
+static const unsigned int gen_clk_f8_pins[] = { GPIOF_8 };
+static const unsigned int gen_clk_f10_pins[] = { GPIOF_10 };
+static const unsigned int gen_clk_a_pins[] = { GPIOA_11 };
+
+/* jtag_a */
+static const unsigned int jtag_a_clk_pins[] = { GPIOF_4 };
+static const unsigned int jtag_a_tms_pins[] = { GPIOF_5 };
+static const unsigned int jtag_a_tdi_pins[] = { GPIOF_6 };
+static const unsigned int jtag_a_tdo_pins[] = { GPIOF_7 };
+
+/* clk_32_in */
+static const unsigned int clk_32k_in_pins[] = { GPIOF_2 };
+
+/* ir in */
+static const unsigned int remote_input_f_pins[] = { GPIOF_3 };
+static const unsigned int remote_input_a_pins[] = { GPIOA_11 };
+
+/* ir out */
+static const unsigned int remote_out_pins[] = { GPIOF_5 };
+
+/* spdif */
+static const unsigned int spdif_in_f6_pins[] = { GPIOF_6 };
+static const unsigned int spdif_in_f7_pins[] = { GPIOF_7 };
+
+/* sw */
+static const unsigned int swclk_pins[] = { GPIOF_4 };
+static const unsigned int swdio_pins[] = { GPIOF_5 };
+
+/* clk_25 */
+static const unsigned int clk25_pins[] = { GPIOF_10 };
+
+/* cec_a */
+static const unsigned int cec_a_pins[] = { GPIOF_2 };
+
+/* cec_b */
+static const unsigned int cec_b_pins[] = { GPIOF_2 };
+
+/* clk12_24 */
+static const unsigned int clk12_24_pins[] = { GPIOF_10 };
+
+/* mclk_0 */
+static const unsigned int mclk_0_pins[] = { GPIOA_0 };
+
+/* tdm_b */
+static const unsigned int tdm_b_sclk_pins[] = { GPIOA_1 };
+static const unsigned int tdm_b_fs_pins[] = { GPIOA_2 };
+static const unsigned int tdm_b_dout0_pins[] = { GPIOA_3 };
+static const unsigned int tdm_b_dout1_pins[] = { GPIOA_4 };
+static const unsigned int tdm_b_dout2_pins[] = { GPIOA_5 };
+static const unsigned int tdm_b_dout3_pins[] = { GPIOA_6 };
+static const unsigned int tdm_b_dout4_pins[] = { GPIOA_7 };
+static const unsigned int tdm_b_dout5_pins[] = { GPIOA_8 };
+static const unsigned int tdm_b_slv_sclk_pins[] = { GPIOA_5 };
+static const unsigned int tdm_b_slv_fs_pins[] = { GPIOA_6 };
+static const unsigned int tdm_b_din0_pins[] = { GPIOA_7 };
+static const unsigned int tdm_b_din1_pins[] = { GPIOA_8 };
+static const unsigned int tdm_b_din2_pins[] = { GPIOA_9 };
+
+/* mclk_vad */
+static const unsigned int mclk_vad_pins[] = { GPIOA_0 };
+
+/* tdm_vad */
+static const unsigned int tdm_vad_sclk_a1_pins[] = { GPIOA_1 };
+static const unsigned int tdm_vad_fs_a2_pins[] = { GPIOA_2 };
+static const unsigned int tdm_vad_sclk_a5_pins[] = { GPIOA_5 };
+static const unsigned int tdm_vad_fs_a6_pins[] = { GPIOA_6 };
+
+/* tst_out */
+static const unsigned int tst_out0_pins[] = { GPIOA_0 };
+static const unsigned int tst_out1_pins[] = { GPIOA_1 };
+static const unsigned int tst_out2_pins[] = { GPIOA_2 };
+static const unsigned int tst_out3_pins[] = { GPIOA_3 };
+static const unsigned int tst_out4_pins[] = { GPIOA_4 };
+static const unsigned int tst_out5_pins[] = { GPIOA_5 };
+static const unsigned int tst_out6_pins[] = { GPIOA_6 };
+static const unsigned int tst_out7_pins[] = { GPIOA_7 };
+static const unsigned int tst_out8_pins[] = { GPIOA_8 };
+static const unsigned int tst_out9_pins[] = { GPIOA_9 };
+static const unsigned int tst_out10_pins[] = { GPIOA_10 };
+static const unsigned int tst_out11_pins[] = { GPIOA_11 };
+
+/* mute */
+static const unsigned int mute_key_pins[] = { GPIOA_4 };
+static const unsigned int mute_en_pins[] = { GPIOA_5 };
+
+static struct meson_pmx_group meson_a1_periphs_groups[] = {
+ GPIO_GROUP(GPIOP_0),
+ GPIO_GROUP(GPIOP_1),
+ GPIO_GROUP(GPIOP_2),
+ GPIO_GROUP(GPIOP_3),
+ GPIO_GROUP(GPIOP_4),
+ GPIO_GROUP(GPIOP_5),
+ GPIO_GROUP(GPIOP_6),
+ GPIO_GROUP(GPIOP_7),
+ GPIO_GROUP(GPIOP_8),
+ GPIO_GROUP(GPIOP_9),
+ GPIO_GROUP(GPIOP_10),
+ GPIO_GROUP(GPIOP_11),
+ GPIO_GROUP(GPIOP_12),
+ GPIO_GROUP(GPIOB_0),
+ GPIO_GROUP(GPIOB_1),
+ GPIO_GROUP(GPIOB_2),
+ GPIO_GROUP(GPIOB_3),
+ GPIO_GROUP(GPIOB_4),
+ GPIO_GROUP(GPIOB_5),
+ GPIO_GROUP(GPIOB_6),
+ GPIO_GROUP(GPIOX_0),
+ GPIO_GROUP(GPIOX_1),
+ GPIO_GROUP(GPIOX_2),
+ GPIO_GROUP(GPIOX_3),
+ GPIO_GROUP(GPIOX_4),
+ GPIO_GROUP(GPIOX_5),
+ GPIO_GROUP(GPIOX_6),
+ GPIO_GROUP(GPIOX_7),
+ GPIO_GROUP(GPIOX_8),
+ GPIO_GROUP(GPIOX_9),
+ GPIO_GROUP(GPIOX_10),
+ GPIO_GROUP(GPIOX_11),
+ GPIO_GROUP(GPIOX_12),
+ GPIO_GROUP(GPIOX_13),
+ GPIO_GROUP(GPIOX_14),
+ GPIO_GROUP(GPIOX_15),
+ GPIO_GROUP(GPIOX_16),
+ GPIO_GROUP(GPIOF_0),
+ GPIO_GROUP(GPIOF_1),
+ GPIO_GROUP(GPIOF_2),
+ GPIO_GROUP(GPIOF_3),
+ GPIO_GROUP(GPIOF_4),
+ GPIO_GROUP(GPIOF_5),
+ GPIO_GROUP(GPIOF_6),
+ GPIO_GROUP(GPIOF_7),
+ GPIO_GROUP(GPIOF_8),
+ GPIO_GROUP(GPIOF_9),
+ GPIO_GROUP(GPIOF_10),
+ GPIO_GROUP(GPIOF_11),
+ GPIO_GROUP(GPIOF_12),
+ GPIO_GROUP(GPIOA_0),
+ GPIO_GROUP(GPIOA_1),
+ GPIO_GROUP(GPIOA_2),
+ GPIO_GROUP(GPIOA_3),
+ GPIO_GROUP(GPIOA_4),
+ GPIO_GROUP(GPIOA_5),
+ GPIO_GROUP(GPIOA_6),
+ GPIO_GROUP(GPIOA_7),
+ GPIO_GROUP(GPIOA_8),
+ GPIO_GROUP(GPIOA_9),
+ GPIO_GROUP(GPIOA_10),
+ GPIO_GROUP(GPIOA_11),
+
+ /* bank P func1 */
+ GROUP(psram_clkn, 1),
+ GROUP(psram_clkp, 1),
+ GROUP(psram_ce_n, 1),
+ GROUP(psram_rst_n, 1),
+ GROUP(psram_adq0, 1),
+ GROUP(psram_adq1, 1),
+ GROUP(psram_adq2, 1),
+ GROUP(psram_adq3, 1),
+ GROUP(psram_adq4, 1),
+ GROUP(psram_adq5, 1),
+ GROUP(psram_adq6, 1),
+ GROUP(psram_adq7, 1),
+ GROUP(psram_dqs_dm, 1),
+
+ /*bank P func2 */
+ GROUP(pwm_e_p, 2),
+
+ /*bank B func1 */
+ GROUP(spif_mo, 1),
+ GROUP(spif_mi, 1),
+ GROUP(spif_wp_n, 1),
+ GROUP(spif_hold_n, 1),
+ GROUP(spif_clk, 1),
+ GROUP(spif_cs, 1),
+ GROUP(pwm_f_b, 1),
+
+ /*bank B func2 */
+ GROUP(sdcard_d0_b, 2),
+ GROUP(sdcard_d1_b, 2),
+ GROUP(sdcard_d2_b, 2),
+ GROUP(sdcard_d3_b, 2),
+ GROUP(sdcard_clk_b, 2),
+ GROUP(sdcard_cmd_b, 2),
+
+ /*bank X func1 */
+ GROUP(sdcard_d0_x, 1),
+ GROUP(sdcard_d1_x, 1),
+ GROUP(sdcard_d2_x, 1),
+ GROUP(sdcard_d3_x, 1),
+ GROUP(sdcard_clk_x, 1),
+ GROUP(sdcard_cmd_x, 1),
+ GROUP(pwm_a_x6, 1),
+ GROUP(tdm_a_dout1, 1),
+ GROUP(tdm_a_dout0, 1),
+ GROUP(tdm_a_fs, 1),
+ GROUP(tdm_a_sclk, 1),
+ GROUP(uart_a_tx, 1),
+ GROUP(uart_a_rx, 1),
+ GROUP(uart_a_cts, 1),
+ GROUP(uart_a_rts, 1),
+ GROUP(pwm_d_x15, 1),
+ GROUP(pwm_e_x16, 1),
+
+ /*bank X func2 */
+ GROUP(i2c2_sck_x0, 2),
+ GROUP(i2c2_sda_x1, 2),
+ GROUP(spi_a_mosi_x2, 2),
+ GROUP(spi_a_ss0_x3, 2),
+ GROUP(spi_a_sclk_x4, 2),
+ GROUP(spi_a_miso_x5, 2),
+ GROUP(tdm_a_din1, 2),
+ GROUP(tdm_a_din0, 2),
+ GROUP(tdm_a_slv_fs, 2),
+ GROUP(tdm_a_slv_sclk, 2),
+ GROUP(i2c3_sck_x, 2),
+ GROUP(i2c3_sda_x, 2),
+ GROUP(pwm_d_x13, 2),
+ GROUP(pwm_e_x14, 2),
+ GROUP(i2c2_sck_x15, 2),
+ GROUP(i2c2_sda_x16, 2),
+
+ /*bank X func3 */
+ GROUP(uart_c_tx_x0, 3),
+ GROUP(uart_c_rx_x1, 3),
+ GROUP(uart_c_cts, 3),
+ GROUP(uart_c_rts, 3),
+ GROUP(pdm_din0_x, 3),
+ GROUP(pdm_din1_x, 3),
+ GROUP(pdm_din2_x, 3),
+ GROUP(pdm_dclk_x, 3),
+ GROUP(uart_c_tx_x15, 3),
+ GROUP(uart_c_rx_x16, 3),
+
+ /*bank X func4 */
+ GROUP(pwm_e_x2, 4),
+ GROUP(pwm_f_x, 4),
+ GROUP(spi_a_mosi_x7, 4),
+ GROUP(spi_a_miso_x8, 4),
+ GROUP(spi_a_ss0_x9, 4),
+ GROUP(spi_a_sclk_x10, 4),
+
+ /*bank X func5 */
+ GROUP(uart_b_tx_x, 5),
+ GROUP(uart_b_rx_x, 5),
+ GROUP(i2c1_sda_x, 5),
+ GROUP(i2c1_sck_x, 5),
+
+ /*bank X func6 */
+ GROUP(pwm_a_x7, 6),
+ GROUP(pwm_b_x, 6),
+ GROUP(pwm_c_x, 6),
+ GROUP(pwm_d_x10, 6),
+
+ /*bank X func7 */
+ GROUP(gen_clk_x, 7),
+
+ /*bank F func1 */
+ GROUP(uart_b_tx_f, 1),
+ GROUP(uart_b_rx_f, 1),
+ GROUP(remote_input_f, 1),
+ GROUP(jtag_a_clk, 1),
+ GROUP(jtag_a_tms, 1),
+ GROUP(jtag_a_tdi, 1),
+ GROUP(jtag_a_tdo, 1),
+ GROUP(gen_clk_f8, 1),
+ GROUP(pwm_a_f10, 1),
+ GROUP(i2c0_sck_f11, 1),
+ GROUP(i2c0_sda_f12, 1),
+
+ /*bank F func2 */
+ GROUP(clk_32k_in, 2),
+ GROUP(pwm_e_f, 2),
+ GROUP(pwm_f_f4, 2),
+ GROUP(remote_out, 2),
+ GROUP(spdif_in_f6, 2),
+ GROUP(spdif_in_f7, 2),
+ GROUP(pwm_a_hiz_f8, 2),
+ GROUP(pwm_a_hiz_f10, 2),
+ GROUP(pwm_d_f, 2),
+ GROUP(pwm_f_f12, 2),
+
+ /*bank F func3 */
+ GROUP(pwm_c_f3, 3),
+ GROUP(swclk, 3),
+ GROUP(swdio, 3),
+ GROUP(pwm_a_f6, 3),
+ GROUP(pwm_b_f, 3),
+ GROUP(pwm_c_f8, 3),
+ GROUP(clk25, 3),
+ GROUP(i2c_slave_sck_f, 3),
+ GROUP(i2c_slave_sda_f, 3),
+
+ /*bank F func4 */
+ GROUP(cec_a, 4),
+ GROUP(i2c3_sck_f, 4),
+ GROUP(i2c3_sda_f, 4),
+ GROUP(pmw_a_hiz_f6, 4),
+ GROUP(pwm_b_hiz, 4),
+ GROUP(pwm_c_hiz, 4),
+ GROUP(i2c0_sck_f9, 4),
+ GROUP(i2c0_sda_f10, 4),
+
+ /*bank F func5 */
+ GROUP(cec_b, 5),
+ GROUP(clk12_24, 5),
+
+ /*bank F func7 */
+ GROUP(gen_clk_f10, 7),
+
+ /*bank A func1 */
+ GROUP(mclk_0, 1),
+ GROUP(tdm_b_sclk, 1),
+ GROUP(tdm_b_fs, 1),
+ GROUP(tdm_b_dout0, 1),
+ GROUP(tdm_b_dout1, 1),
+ GROUP(tdm_b_dout2, 1),
+ GROUP(tdm_b_dout3, 1),
+ GROUP(tdm_b_dout4, 1),
+ GROUP(tdm_b_dout5, 1),
+ GROUP(remote_input_a, 1),
+
+ /*bank A func2 */
+ GROUP(pwm_e_a, 2),
+ GROUP(tdm_b_slv_sclk, 2),
+ GROUP(tdm_b_slv_fs, 2),
+ GROUP(tdm_b_din0, 2),
+ GROUP(tdm_b_din1, 2),
+ GROUP(tdm_b_din2, 2),
+ GROUP(i2c1_sda_a, 2),
+ GROUP(i2c1_sck_a, 2),
+
+ /*bank A func3 */
+ GROUP(i2c2_sck_a4, 3),
+ GROUP(i2c2_sda_a5, 3),
+ GROUP(pdm_din2_a, 3),
+ GROUP(pdm_din1_a, 3),
+ GROUP(pdm_din0_a, 3),
+ GROUP(pdm_dclk, 3),
+ GROUP(pwm_c_a, 3),
+ GROUP(pwm_b_a, 3),
+
+ /*bank A func4 */
+ GROUP(pwm_a_a, 4),
+ GROUP(spi_a_mosi_a, 4),
+ GROUP(spi_a_miso_a, 4),
+ GROUP(spi_a_ss0_a, 4),
+ GROUP(spi_a_sclk_a, 4),
+ GROUP(i2c_slave_sck_a, 4),
+ GROUP(i2c_slave_sda_a, 4),
+
+ /*bank A func5 */
+ GROUP(mclk_vad, 5),
+ GROUP(tdm_vad_sclk_a1, 5),
+ GROUP(tdm_vad_fs_a2, 5),
+ GROUP(tdm_vad_sclk_a5, 5),
+ GROUP(tdm_vad_fs_a6, 5),
+ GROUP(i2c2_sck_a8, 5),
+ GROUP(i2c2_sda_a9, 5),
+
+ /*bank A func6 */
+ GROUP(tst_out0, 6),
+ GROUP(tst_out1, 6),
+ GROUP(tst_out2, 6),
+ GROUP(tst_out3, 6),
+ GROUP(tst_out4, 6),
+ GROUP(tst_out5, 6),
+ GROUP(tst_out6, 6),
+ GROUP(tst_out7, 6),
+ GROUP(tst_out8, 6),
+ GROUP(tst_out9, 6),
+ GROUP(tst_out10, 6),
+ GROUP(tst_out11, 6),
+
+ /*bank A func7 */
+ GROUP(mute_key, 7),
+ GROUP(mute_en, 7),
+ GROUP(gen_clk_a, 7),
+};
+
+static const char * const gpio_periphs_groups[] = {
+ "GPIOP_0", "GPIOP_1", "GPIOP_2", "GPIOP_3", "GPIOP_4",
+ "GPIOP_5", "GPIOP_6", "GPIOP_7", "GPIOP_8", "GPIOP_9",
+ "GPIOP_10", "GPIOP_11", "GPIOP_12",
+
+ "GPIOB_0", "GPIOB_1", "GPIOB_2", "GPIOB_3", "GPIOB_4",
+ "GPIOB_5", "GPIOB_6",
+
+ "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4",
+ "GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9",
+ "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
+ "GPIOX_15", "GPIOX_16",
+
+ "GPIOF_0", "GPIOF_1", "GPIOF_2", "GPIOF_3", "GPIOF_4",
+ "GPIOF_5", "GPIOF_6", "GPIOF_7", "GPIOF_8", "GPIOF_9",
+ "GPIOF_10", "GPIOF_11", "GPIOF_12",
+
+ "GPIOA_0", "GPIOA_1", "GPIOA_2", "GPIOA_3", "GPIOA_4",
+ "GPIOA_5", "GPIOA_6", "GPIOA_7", "GPIOA_8", "GPIOA_9",
+ "GPIOA_10", "GPIOA_11",
+};
+
+static const char * const psram_groups[] = {
+ "psram_clkn", "psram_clkp", "psram_ce_n", "psram_rst_n", "psram_adq0",
+ "psram_adq1", "psram_adq2", "psram_adq3", "psram_adq4", "psram_adq5",
+ "psram_adq6", "psram_adq7", "psram_dqs_dm",
+};
+
+static const char * const pwm_a_groups[] = {
+ "pwm_a_x6", "pwm_a_x7", "pwm_a_f10", "pwm_a_f6", "pwm_a_a",
+};
+
+static const char * const pwm_b_groups[] = {
+ "pwm_b_x", "pwm_b_f", "pwm_b_a",
+};
+
+static const char * const pwm_c_groups[] = {
+ "pwm_c_x", "pwm_c_f3", "pwm_c_f8", "pwm_c_a",
+};
+
+static const char * const pwm_d_groups[] = {
+ "pwm_d_x15", "pwm_d_x13", "pwm_d_x10", "pwm_d_f",
+};
+
+static const char * const pwm_e_groups[] = {
+ "pwm_e_p", "pwm_e_x16", "pwm_e_x14", "pwm_e_x2", "pwm_e_f",
+ "pwm_e_a",
+};
+
+static const char * const pwm_f_groups[] = {
+ "pwm_f_b", "pwm_f_x", "pwm_f_f4", "pwm_f_f12",
+};
+
+static const char * const pwm_a_hiz_groups[] = {
+ "pwm_a_hiz_f8", "pwm_a_hiz_f10", "pwm_a_hiz_f6",
+};
+
+static const char * const pwm_b_hiz_groups[] = {
+ "pwm_b_hiz",
+};
+
+static const char * const pwm_c_hiz_groups[] = {
+ "pwm_c_hiz",
+};
+
+static const char * const spif_groups[] = {
+ "spif_mo", "spif_mi", "spif_wp_n", "spif_hold_n", "spif_clk",
+ "spif_cs",
+};
+
+static const char * const sdcard_groups[] = {
+ "sdcard_d0_b", "sdcard_d1_b", "sdcard_d2_b", "sdcard_d3_b",
+ "sdcard_clk_b", "sdcard_cmd_b",
+
+ "sdcard_d0_x", "sdcard_d1_x", "sdcard_d2_x", "sdcard_d3_x",
+ "sdcard_clk_x", "sdcard_cmd_x",
+};
+
+static const char * const tdm_a_groups[] = {
+ "tdm_a_din0", "tdm_a_din1", "tdm_a_fs", "tdm_a_sclk",
+ "tdm_a_slv_fs", "tdm_a_slv_sclk", "tdm_a_dout0", "tdm_a_dout1",
+};
+
+static const char * const uart_a_groups[] = {
+ "uart_a_tx", "uart_a_rx", "uart_a_cts", "uart_a_rts",
+};
+
+static const char * const uart_b_groups[] = {
+ "uart_b_tx_x", "uart_b_rx_x", "uart_b_tx_f", "uart_b_rx_f",
+};
+
+static const char * const uart_c_groups[] = {
+ "uart_c_tx_x0", "uart_c_rx_x1", "uart_c_cts", "uart_c_rts",
+ "uart_c_tx_x15", "uart_c_rx_x16",
+};
+
+static const char * const i2c0_groups[] = {
+ "i2c0_sck_f11", "i2c0_sda_f12", "i2c0_sck_f9", "i2c0_sda_f10",
+};
+
+static const char * const i2c1_groups[] = {
+ "i2c1_sda_x", "i2c1_sck_x", "i2c1_sda_a", "i2c1_sck_a",
+};
+
+static const char * const i2c2_groups[] = {
+ "i2c2_sck_x0", "i2c2_sda_x1", "i2c2_sck_x15", "i2c2_sda_x16",
+ "i2c2_sck_a4", "i2c2_sda_a5", "i2c2_sck_a8", "i2c2_sda_a9",
+};
+
+static const char * const i2c3_groups[] = {
+ "i2c3_sck_x", "i2c3_sda_x", "i2c3_sck_f", "i2c3_sda_f",
+};
+
+static const char * const i2c_slave_groups[] = {
+ "i2c_slave_sda_a", "i2c_slave_sck_a",
+ "i2c_slave_sda_f", "i2c_slave_sck_f",
+};
+
+static const char * const spi_a_groups[] = {
+ "spi_a_mosi_x2", "spi_a_ss0_x3", "spi_a_sclk_x4", "spi_a_miso_x5",
+ "spi_a_mosi_x7", "spi_a_miso_x8", "spi_a_ss0_x9", "spi_a_sclk_x10",
+
+ "spi_a_mosi_a", "spi_a_miso_a", "spi_a_ss0_a", "spi_a_sclk_a",
+};
+
+static const char * const pdm_groups[] = {
+ "pdm_din0_x", "pdm_din1_x", "pdm_din2_x", "pdm_dclk_x", "pdm_din2_a",
+ "pdm_din1_a", "pdm_din0_a", "pdm_dclk",
+};
+
+static const char * const gen_clk_groups[] = {
+ "gen_clk_x", "gen_clk_f8", "gen_clk_f10", "gen_clk_a",
+};
+
+static const char * const remote_input_groups[] = {
+ "remote_input_f",
+ "remote_input_a",
+};
+
+static const char * const jtag_a_groups[] = {
+ "jtag_a_clk", "jtag_a_tms", "jtag_a_tdi", "jtag_a_tdo",
+};
+
+static const char * const clk_32k_in_groups[] = {
+ "clk_32k_in",
+};
+
+static const char * const remote_out_groups[] = {
+ "remote_out",
+};
+
+static const char * const spdif_in_groups[] = {
+ "spdif_in_f6", "spdif_in_f7",
+};
+
+static const char * const sw_groups[] = {
+ "swclk", "swdio",
+};
+
+static const char * const clk25_groups[] = {
+ "clk_25",
+};
+
+static const char * const cec_a_groups[] = {
+ "cec_a",
+};
+
+static const char * const cec_b_groups[] = {
+ "cec_b",
+};
+
+static const char * const clk12_24_groups[] = {
+ "clk12_24",
+};
+
+static const char * const mclk_0_groups[] = {
+ "mclk_0",
+};
+
+static const char * const tdm_b_groups[] = {
+ "tdm_b_din0", "tdm_b_din1", "tdm_b_din2",
+ "tdm_b_sclk", "tdm_b_fs", "tdm_b_dout0", "tdm_b_dout1",
+ "tdm_b_dout2", "tdm_b_dout3", "tdm_b_dout4", "tdm_b_dout5",
+ "tdm_b_slv_sclk", "tdm_b_slv_fs",
+};
+
+static const char * const mclk_vad_groups[] = {
+ "mclk_vad",
+};
+
+static const char * const tdm_vad_groups[] = {
+ "tdm_vad_sclk_a1", "tdm_vad_fs_a2", "tdm_vad_sclk_a5", "tdm_vad_fs_a6",
+};
+
+static const char * const tst_out_groups[] = {
+ "tst_out0", "tst_out1", "tst_out2", "tst_out3",
+ "tst_out4", "tst_out5", "tst_out6", "tst_out7",
+ "tst_out8", "tst_out9", "tst_out10", "tst_out11",
+};
+
+static const char * const mute_groups[] = {
+ "mute_key", "mute_en",
+};
+
+static struct meson_pmx_func meson_a1_periphs_functions[] = {
+ FUNCTION(gpio_periphs),
+ FUNCTION(psram),
+ FUNCTION(pwm_a),
+ FUNCTION(pwm_b),
+ FUNCTION(pwm_c),
+ FUNCTION(pwm_d),
+ FUNCTION(pwm_e),
+ FUNCTION(pwm_f),
+ FUNCTION(pwm_a_hiz),
+ FUNCTION(pwm_b_hiz),
+ FUNCTION(pwm_c_hiz),
+ FUNCTION(spif),
+ FUNCTION(sdcard),
+ FUNCTION(tdm_a),
+ FUNCTION(uart_a),
+ FUNCTION(uart_b),
+ FUNCTION(uart_c),
+ FUNCTION(i2c0),
+ FUNCTION(i2c1),
+ FUNCTION(i2c2),
+ FUNCTION(i2c3),
+ FUNCTION(spi_a),
+ FUNCTION(pdm),
+ FUNCTION(gen_clk),
+ FUNCTION(remote_input),
+ FUNCTION(jtag_a),
+ FUNCTION(clk_32k_in),
+ FUNCTION(remote_out),
+ FUNCTION(spdif_in),
+ FUNCTION(sw),
+ FUNCTION(clk25),
+ FUNCTION(cec_a),
+ FUNCTION(cec_b),
+ FUNCTION(clk12_24),
+ FUNCTION(mclk_0),
+ FUNCTION(tdm_b),
+ FUNCTION(mclk_vad),
+ FUNCTION(tdm_vad),
+ FUNCTION(tst_out),
+ FUNCTION(mute),
+};
+
+static struct meson_bank meson_a1_periphs_banks[] = {
+ /* name first last irq pullen pull dir out in ds*/
+ BANK_DS("P", GPIOP_0, GPIOP_12, 0, 12, 0x3, 0, 0x4, 0,
+ 0x2, 0, 0x1, 0, 0x0, 0, 0x5, 0),
+ BANK_DS("B", GPIOB_0, GPIOB_6, 13, 19, 0x13, 0, 0x14, 0,
+ 0x12, 0, 0x11, 0, 0x10, 0, 0x15, 0),
+ BANK_DS("X", GPIOX_0, GPIOX_16, 20, 36, 0x23, 0, 0x24, 0,
+ 0x22, 0, 0x21, 0, 0x20, 0, 0x25, 0),
+ BANK_DS("F", GPIOF_0, GPIOF_12, 37, 49, 0x33, 0, 0x34, 0,
+ 0x32, 0, 0x31, 0, 0x30, 0, 0x35, 0),
+ BANK_DS("A", GPIOA_0, GPIOA_11, 50, 61, 0x43, 0, 0x44, 0,
+ 0x42, 0, 0x41, 0, 0x40, 0, 0x45, 0),
+};
+
+static struct meson_pmx_bank meson_a1_periphs_pmx_banks[] = {
+ /* name first lask reg offset */
+ BANK_PMX("P", GPIOP_0, GPIOP_12, 0x0, 0),
+ BANK_PMX("B", GPIOB_0, GPIOB_6, 0x2, 0),
+ BANK_PMX("X", GPIOX_0, GPIOX_16, 0x3, 0),
+ BANK_PMX("F", GPIOF_0, GPIOF_12, 0x6, 0),
+ BANK_PMX("A", GPIOA_0, GPIOA_11, 0x8, 0),
+};
+
+static struct meson_axg_pmx_data meson_a1_periphs_pmx_banks_data = {
+ .pmx_banks = meson_a1_periphs_pmx_banks,
+ .num_pmx_banks = ARRAY_SIZE(meson_a1_periphs_pmx_banks),
+};
+
+static struct meson_pinctrl_data meson_a1_periphs_pinctrl_data = {
+ .name = "periphs-banks",
+ .pins = meson_a1_periphs_pins,
+ .groups = meson_a1_periphs_groups,
+ .funcs = meson_a1_periphs_functions,
+ .banks = meson_a1_periphs_banks,
+ .num_pins = ARRAY_SIZE(meson_a1_periphs_pins),
+ .num_groups = ARRAY_SIZE(meson_a1_periphs_groups),
+ .num_funcs = ARRAY_SIZE(meson_a1_periphs_functions),
+ .num_banks = ARRAY_SIZE(meson_a1_periphs_banks),
+ .pmx_ops = &meson_axg_pmx_ops,
+ .pmx_data = &meson_a1_periphs_pmx_banks_data,
+ .reg_layout = A1_LAYOUT,
+};
+
+static const struct of_device_id meson_a1_pinctrl_dt_match[] = {
+ {
+ .compatible = "amlogic,meson-a1-periphs-pinctrl",
+ .data = &meson_a1_periphs_pinctrl_data,
+ },
+ { },
+};
+
+static struct platform_driver meson_a1_pinctrl_driver = {
+ .probe = meson_pinctrl_probe,
+ .driver = {
+ .name = "meson-a1-pinctrl",
+ .of_match_table = meson_a1_pinctrl_dt_match,
+ },
+};
+
+builtin_platform_driver(meson_a1_pinctrl_driver);
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index 8bba9d0..885b89d 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -688,8 +688,12 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
pc->reg_ds = meson_map_resource(pc, gpio_np, "ds");
if (IS_ERR(pc->reg_ds)) {
- dev_dbg(pc->dev, "ds registers not found - skipping\n");
- pc->reg_ds = NULL;
+ if (pc->data->reg_layout == A1_LAYOUT) {
+ pc->reg_ds = pc->reg_pullen;
+ } else {
+ dev_dbg(pc->dev, "ds registers not found - skipping\n");
+ pc->reg_ds = NULL;
+ }
}
return 0;
diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h
index c696f32..3d0c58d 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.h
+++ b/drivers/pinctrl/meson/pinctrl-meson.h
@@ -80,6 +80,14 @@ enum meson_pinconf_drv {
};
/**
+ * enum meson_reg_layout - identify two types of reg layout
+ */
+enum meson_reg_layout {
+ LEGACY_LAYOUT,
+ A1_LAYOUT,
+};
+
+/**
* struct meson bank
*
* @name: bank name
@@ -114,6 +122,7 @@ struct meson_pinctrl_data {
unsigned int num_banks;
const struct pinmux_ops *pmx_ops;
void *pmx_data;
+ unsigned int reg_layout;
};
struct meson_pinctrl {
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox