* [PATCH v2 1/2] PCI: kirin: Add MSI support
From: Yao Chen @ 2018-05-09 8:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525854012-24228-1-git-send-email-chenyao11@huawei.com>
Add support for MSI.
Signed-off-by: Yao Chen <chenyao11@huawei.com>
---
drivers/pci/dwc/pcie-kirin.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/drivers/pci/dwc/pcie-kirin.c b/drivers/pci/dwc/pcie-kirin.c
index d2970a0..4328efe 100644
--- a/drivers/pci/dwc/pcie-kirin.c
+++ b/drivers/pci/dwc/pcie-kirin.c
@@ -426,9 +426,28 @@ static int kirin_pcie_establish_link(struct pcie_port *pp)
return 0;
}
+static irqreturn_t kirin_pcie_msi_irq_handler(int irq, void *arg)
+{
+ struct pcie_port *pp = arg;
+
+ return dw_handle_msi_irq(pp);
+}
+
+static void kirin_pcie_msi_init(struct pcie_port *pp)
+{
+ dw_pcie_msi_init(pp);
+}
+
+static void kirin_pcie_enable_interrupts(struct pcie_port *pp)
+{
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ kirin_pcie_msi_init(pp);
+}
+
static int kirin_pcie_host_init(struct pcie_port *pp)
{
kirin_pcie_establish_link(pp);
+ kirin_pcie_enable_interrupts(pp);
return 0;
}
@@ -448,6 +467,26 @@ static int kirin_pcie_host_init(struct pcie_port *pp)
static int __init kirin_add_pcie_port(struct dw_pcie *pci,
struct platform_device *pdev)
{
+ int ret;
+
+ if (IS_ENABLED(CONFIG_PCI_MSI)) {
+ pci->pp.msi_irq = platform_get_irq(pdev, 0);
+ if (!pci->pp.msi_irq) {
+ dev_err(&pdev->dev, "failed to get msi irq[%d]\n",
+ pci->pp.msi_irq);
+ return -ENODEV;
+ }
+ ret = devm_request_irq(&pdev->dev, pci->pp.msi_irq,
+ kirin_pcie_msi_irq_handler,
+ IRQF_SHARED | IRQF_NO_THREAD,
+ "kirin_pcie_msi", &pci->pp);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request msi irq[%d]\n",
+ pci->pp.msi_irq);
+ return ret;
+ }
+ }
+
pci->pp.ops = &kirin_pcie_host_ops;
return dw_pcie_host_init(&pci->pp);
--
1.9.1
^ permalink raw reply related
* [PATCH v2 0/2] Add MSI support
From: Yao Chen @ 2018-05-09 8:20 UTC (permalink / raw)
To: linux-arm-kernel
Changes between V2 and V1
=========================
1. seperate DT binding patch.
2. fix issues according to review comments
(1)from Bjorn Helgaas: Update the style of subject and changelog.
(2)from Bjorn Helgaas: Add msi irq number in the message.
(3)from Bjorn Helgaas: Delete unnecessary code 'pci->pp.root_bus_nr = -1'.
(4)from Dmitry Shmidt: Fix typing error. Replace 'interrupts-names' of 'interrupt-names'.
Yao Chen (2):
PCI: kirin: Add MSI support
arm64: dts: hi3660: Add pcie msi interrupt attribute
arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 2 ++
drivers/pci/dwc/pcie-kirin.c | 39 +++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
--
1.9.1
^ permalink raw reply
* [PATCH v7 14/24] ASoC: qdsp6: q6asm: Add q6asm driver
From: Srinivas Kandagatla @ 2018-05-09 8:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3e7601d4-0304-3aa1-66cc-617b99727567@codeaurora.org>
On 09/05/18 09:10, Banajit Goswami wrote:
>>
> MAX_SESSIONS should be 8?
>
Yep, will update it in v8.
thanks,
srini
> Otherwise LGTM.
> Once addressed about, add acked-by-
> Acked-by: Banajit Goswami <bgoswami@codeaurora.org>
^ permalink raw reply
* [PATCH v7 14/24] ASoC: qdsp6: q6asm: Add q6asm driver
From: Banajit Goswami @ 2018-05-09 8:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180501120820.11016-15-srinivas.kandagatla@linaro.org>
On 5/1/2018 5:08 AM, Srinivas Kandagatla wrote:
> This patch adds basic support to Q6 ASM (Audio Stream Manager) module on
> Q6DSP. ASM supports up to 8 concurrent streams. each stream can be setup
> as playback/capture. ASM provides top control functions like
> Pause/flush/resume for playback and record. ASM can Create/destroy encoder,
> decoder and also provides POPP dynamic services.
>
> This patch adds support to basic features to allow hdmi playback.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Reviewed-and-tested-by: Rohit kumar <rohitkr@codeaurora.org>
> ---
> sound/soc/qcom/Kconfig | 4 +
> sound/soc/qcom/qdsp6/Makefile | 1 +
> sound/soc/qcom/qdsp6/q6asm.c | 215 ++++++++++++++++++++++++++++++++++++++++++
> sound/soc/qcom/qdsp6/q6asm.h | 15 +++
> 4 files changed, 235 insertions(+)
> create mode 100644 sound/soc/qcom/qdsp6/q6asm.c
> create mode 100644 sound/soc/qcom/qdsp6/q6asm.h
>
> diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
> index 971127edbc23..941774abd94f 100644
> --- a/sound/soc/qcom/Kconfig
> +++ b/sound/soc/qcom/Kconfig
> @@ -53,6 +53,9 @@ config SND_SOC_QDSP6_AFE
> config SND_SOC_QDSP6_ADM
> tristate
>
> +config SND_SOC_QDSP6_ASM
<snip>
> +static const struct of_device_id q6asm_device_id[] = {
> + { .compatible = "qcom,q6asm" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, q6asm_device_id);
> +
> +static struct apr_driver qcom_q6asm_driver = {
> + .probe = q6asm_probe,
> + .remove = q6asm_remove,
> + .callback = q6asm_srvc_callback,
> + .driver = {
> + .name = "qcom-q6asm",
> + .of_match_table = of_match_ptr(q6asm_device_id),
> + },
> +};
> +
> +module_apr_driver(qcom_q6asm_driver);
> +MODULE_DESCRIPTION("Q6 Audio Stream Manager driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/sound/soc/qcom/qdsp6/q6asm.h b/sound/soc/qcom/qdsp6/q6asm.h
> new file mode 100644
> index 000000000000..92cc0efaa2c8
> --- /dev/null
> +++ b/sound/soc/qcom/qdsp6/q6asm.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __Q6_ASM_H__
> +#define __Q6_ASM_H__
> +
> +#define MAX_SESSIONS 16
MAX_SESSIONS should be 8?
Otherwise LGTM.
Once addressed about, add acked-by-
Acked-by: Banajit Goswami <bgoswami@codeaurora.org>
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH v7 13/24] ASoC: qdsp6: q6adm: Add q6adm driver
From: Srinivas Kandagatla @ 2018-05-09 8:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <e9a97387-2bd7-9733-5946-50091aec93a0@codeaurora.org>
On 09/05/18 08:55, Banajit Goswami wrote:
>> + */
>> +int q6adm_close(struct device *dev, int port_id, int perf_mode, int
>> copp_idx)
> perf_mode unused param. Remove for now. Can be added back when needed.
>
> Otherwise LGTM.
Yep, will do that thanks.
--srini
> Once fixed above, add acked-by
> Acked-by: Banajit Goswami <bgoswami@codeaurora.org>
^ permalink raw reply
* [PATCH 1/5] dt-bindings: pinctrl: document the STMFX pinctrl bindings
From: Amelie DELAUNAY @ 2018-05-09 7:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACRpkdYOMjjYyWQz7PK34jqUK7z5-CmH1HY6un4k8nBn7Cq8ag@mail.gmail.com>
On 04/26/2018 02:49 PM, Linus Walleij wrote:
> On Mon, Apr 16, 2018 at 8:19 PM, Rob Herring <robh@kernel.org> wrote:
>> On Wed, Apr 11, 2018 at 11:47:01AM +0200, Amelie Delaunay wrote:
>>> This patch adds documentation of device tree bindings for the
>>> STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander.
>>>
>>> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
>
>>> + stmfxpinctrl: stmfx at 42 {
>>> + compatible = "st,stmfx-0300";
>>> + reg = <0x42>;
>>> + interrupt-parent = <&gpioi>;
>>> + interrupts = <8 IRQ_TYPE_EDGE_RISING>;
>>> + vdd-supply = <&v3v3>;
>>> + status = "okay";
>>
>> Don't show status in examples.
>>
>>> +
>>> + stmfxgpio: gpio {
>>
>> Why does this need to be a sub node? Are there functions beyond GPIO?
>
> Amelie can answer to whether there are, I suspect there
> are and in the review of patch 2 I suggest a MFD parent
> and parent/child spawning of a MFD child for the GPIO
> and pin control device.
>
> Yours,
> Linus Walleij
>
Indeed, stmfx has other functions than GPIO. But, after comments done
here: [1] and there: [2], it has been decided to move MFD parent/GPIO
child drivers into a single PINCTRL/GPIO driver because of the following
reasons:
- Other stmfx functions (IDD measurement and TouchScreen controller) are
not used on any of the boards using an stmfx and supported by Linux, so
no way to test these functions, and no need to maintain them while they
are not being used.
- But, in the case a new board will use more than GPIO function on
stmfx, the actual implementation allow to easily extract common init
part of stmfx and put it in an MFD driver.
So I could remove gpio sub-node and put its contents in stmfx node and
keep single PINCTRL/GPIO driver for the time being.
Please advise,
Thanks,
Amelie
[1] https://lkml.org/lkml/2018/2/12/265
[2] https://lkml.org/lkml/2018/2/21/1503
^ permalink raw reply
* [PATCH v7 13/24] ASoC: qdsp6: q6adm: Add q6adm driver
From: Banajit Goswami @ 2018-05-09 7:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180501120820.11016-14-srinivas.kandagatla@linaro.org>
On 5/1/2018 5:08 AM, Srinivas Kandagatla wrote:
> This patch adds support to Q6ADM (Audio Device Manager) module in
> q6dsp. ADM performs routing between audio streams and AFE ports.
> It does Rate matching for streams going to devices driven by
> different clocks, it handles volume ramping, Mixing with channel
> and bit-width. ADM creates and destroys dynamic COPP services
> for device-related audio processing as needed.
>
> This patch adds basic support to ADM.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Reviewed-and-tested-by: Rohit kumar <rohitkr@codeaurora.org>
> ---
> sound/soc/qcom/Kconfig | 4 +
> sound/soc/qcom/qdsp6/Makefile | 1 +
> sound/soc/qcom/qdsp6/q6adm.c | 636 ++++++++++++++++++++++++++++++++++++++++++
> sound/soc/qcom/qdsp6/q6adm.h | 25 ++
> 4 files changed, 666 insertions(+)
> create mode 100644 sound/soc/qcom/qdsp6/q6adm.c
> create mode 100644 sound/soc/qcom/qdsp6/q6adm.h
>
> diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
> index bb0a2afb0563..971127edbc23 100644
> --- a/sound/soc/qcom/Kconfig
> +++ b/sound/soc/qcom/Kconfig
> @@ -50,12 +50,16 @@ config SND_SOC_QDSP6_CORE
> config SND_SOC_QDSP6_AFE
> tristate
<snip>
> +}
> +
> +static int q6adm_callback(struct apr_device *adev, struct apr_resp_pkt *data)
> +{
> + struct aprv2_ibasic_rsp_result_t *result = data->payload;
> + int port_idx, copp_idx;
> + struct apr_hdr *hdr = &data->hdr;
> + struct q6copp *copp;
> + struct q6adm *adm = dev_get_drvdata(&adev->dev);
> +
> + if (!data->payload_size)
> + return 0;
> +
> +
> + copp_idx = (hdr->token) & 0XFF;
> + port_idx = ((hdr->token) >> 16) & 0xFF;
> + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) {
> + dev_err(&adev->dev, "Invalid port idx %d token %d\n",
> + port_idx, hdr->token);
> + return 0;
> + }
> + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
> + dev_err(&adev->dev, "Invalid copp idx %d token %d\n",
> + copp_idx, hdr->token);
> + return 0;
> + }
> +
> + switch (hdr->opcode) {
> + case APR_BASIC_RSP_RESULT: {
> + if (result->status != 0) {
> + dev_err(&adev->dev, "cmd = 0x%x return error = 0x%x\n",
> + result->opcode, result->status);
> + }
> + switch (result->opcode) {
> + case ADM_CMD_DEVICE_OPEN_V5:
> + case ADM_CMD_DEVICE_CLOSE_V5:
> + copp = adm_find_copp(adm, port_idx, copp_idx);
> + if (!copp)
> + return 0;
> +
> + copp->result = *result;
> + wake_up(&copp->wait);
> + break;
> + case ADM_CMD_MATRIX_MAP_ROUTINGS_V5:
> + adm->result = *result;
> + wake_up(&adm->matrix_map_wait);
> + break;
> +
> + default:
> + dev_err(&adev->dev, "Unknown Cmd: 0x%x\n",
> + result->opcode);
> + break;
> + }
> + return 0;
> + }
> + case ADM_CMDRSP_DEVICE_OPEN_V5: {
> + struct adm_cmd_rsp_device_open_v5 {
> + u32 status;
> + u16 copp_id;
> + u16 reserved;
> + } __packed * open = data->payload;
> +
> + open = data->payload;
Isn't this repetition of previous line from struct definition?
> +
> + return c;
> +}
> +
> +static int q6adm_apr_send_copp_pkt(struct q6adm *adm, struct q6copp *copp,
> + struct apr_pkt *pkt, uint32_t rsp_opcode)
> +{
> + struct device *dev = adm->dev;
> + uint32_t opcode = pkt->hdr.opcode;
> + int ret;
> +
> + mutex_lock(&adm->lock);
> + copp->result.opcode = 0;
> + copp->result.status = 0;
> + ret = apr_send_pkt(adm->apr, pkt);
> + if (ret < 0) {
> + dev_err(dev, "Failed to send APR packet\n");
> + ret = -EINVAL;
> + goto err;
> + }
> +
> + /* Wait for the callback with copp id */
> + if (rsp_opcode)
> + ret = wait_event_timeout(copp->wait,
> + (copp->result.opcode == opcode) ||
> + (copp->result.opcode == rsp_opcode),
> + msecs_to_jiffies(TIMEOUT_MS));
> + else
> + ret = wait_event_timeout(copp->wait,
> + (copp->result.opcode == opcode),
> + msecs_to_jiffies(TIMEOUT_MS));
> +
> + if (!ret) {
> + dev_err(dev, "ADM copp cmd timedout\n");
> + ret = -EINVAL;
ret = -ETIMEDOUT;
> + } else if (copp->result.status > 0) {
> + dev_err(dev, "DSP returned error[%d]\n",
> + copp->result.status);
> + ret = -EINVAL;
> + }
> +
> +err:
> + mutex_unlock(&adm->lock);
> + return ret;
> +}
> +
> +static int q6adm_device_close(struct q6adm *adm, struct q6copp *copp,
> + int port_id, int copp_idx)
> +{
> + struct apr_pkt close;
> +
> + close.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
> + APR_HDR_LEN(APR_HDR_SIZE),
> + APR_PKT_VER);
> + close.hdr.pkt_size = sizeof(close);
> + close.hdr.src_port = port_id;
> + close.hdr.dest_port = copp->id;
> + close.hdr.token = port_id << 16 | copp_idx;
> + close.hdr.opcode = ADM_CMD_DEVICE_CLOSE_V5;
> +
> + return q6adm_apr_send_copp_pkt(adm, copp, &close, 0);
> +}
> +
> +static void adm_free_copp(struct kref *ref)
> +{
> + struct q6copp *c = container_of(ref, struct q6copp, refcount);
> + struct q6adm *adm = c->adm;
> + int port_idx = c->afe_port;
> + int copp_idx = c->copp_idx;
> + unsigned long flags;
> + int ret;
> +
> + ret = q6adm_device_close(adm, c, port_idx, copp_idx);
> + if (ret < 0)
> + dev_err(adm->dev, "Failed to close copp %d\n", ret);
> +
> + clear_bit(c->copp_idx, &adm->copp_bitmap[port_idx]);
> + spin_lock_irqsave(&adm->copps_list_lock, flags);
> + list_del(&c->node);
> + spin_unlock_irqrestore(&adm->copps_list_lock, flags);
> + kfree(c);
> +}
> +
> +static struct q6copp *adm_find_matching_copp(struct q6adm *adm,
> + int port_id, int topology,
> + int mode, int rate, int channel_mode,
> + int bit_width, int app_type)
> +{
> + unsigned long flags;
> + struct q6copp *c;
> +
> + spin_lock_irqsave(&adm->copps_list_lock, flags);
> +
> + list_for_each_entry(c, &adm->copps_list, node) {
> + if ((port_id == c->afe_port) && (topology == c->topology) &&
> + (mode == c->mode) && (rate == c->rate) &&
> + (bit_width == c->bit_width) && (app_type == c->app_type)) {
> + spin_unlock_irqrestore(&adm->copps_list_lock, flags);
> + kref_get(&c->refcount);
> + return c;
> + }
> + }
> + spin_unlock_irqrestore(&adm->copps_list_lock, flags);
> +
> + c = adm_alloc_copp(adm, port_id);
> + if (IS_ERR_OR_NULL(c))
> + return ERR_CAST(c);
> +
> + kref_init(&c->refcount);
> + c->topology = topology;
> + c->mode = mode;
> + c->rate = rate;
> + c->channels = channel_mode;
> + c->bit_width = bit_width;
> + c->app_type = app_type;
> +
> + spin_lock_irqsave(&adm->copps_list_lock, flags);
> + list_add_tail(&c->node, &adm->copps_list);
> + spin_unlock_irqrestore(&adm->copps_list_lock, flags);
> +
> + return c;
> +
Remove extra blank line at end of function.
> +}
> +
> +static int q6adm_device_open(struct q6adm *adm, struct q6copp *copp,
> + int port_id, int path, int topology,
> + int channel_mode, int bit_width, int rate)
<snip>
> +
> +/**
> + * q6adm_matrix_map() - Map asm streams and afe ports using payload
> + *
> + * @dev: Pointer to adm child device.
> + * @path: playback or capture path.
> + * @payload_map: map between session id and afe ports.
> + * @perf_mode: Performace mode.
> + *
> + * Return: Will be an negative on error or a zero on success.
> + */
> +int q6adm_matrix_map(struct device *dev, int path,
> + struct route_payload payload_map, int perf_mode)
> +{
> + struct q6adm *adm = dev_get_drvdata(dev->parent);
> + struct q6adm_cmd_matrix_map_routings_v5 *route;
> + struct q6adm_session_map_node_v5 *node;
> + struct apr_pkt *pkt;
> + uint16_t *copps_list;
> + int pkt_size, ret, i, copp_idx;
> + void *matrix_map = NULL;
> + struct q6copp *copp;
> +
> + /* Assumes port_ids have already been validated during adm_open */
> + pkt_size = (APR_HDR_SIZE + sizeof(*route) + sizeof(*node) +
> + (sizeof(uint32_t) * payload_map.num_copps));
> +
> + matrix_map = kzalloc(pkt_size, GFP_KERNEL);
> + if (!matrix_map)
> + return -ENOMEM;
> +
> + pkt = matrix_map;
> + route = matrix_map + APR_HDR_SIZE;
> + node = matrix_map + APR_HDR_SIZE + sizeof(*route);
> + copps_list = matrix_map + APR_HDR_SIZE + sizeof(*route) + sizeof(*node);
> +
> + pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
> + APR_HDR_LEN(APR_HDR_SIZE),
> + APR_PKT_VER);
> + pkt->hdr.pkt_size = pkt_size;
> + pkt->hdr.token = 0;
> + pkt->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5;
> + route->num_sessions = 1;
> +
> + switch (path) {
> + case ADM_PATH_PLAYBACK:
> + route->matrix_id = ADM_MATRIX_ID_AUDIO_RX;
> + break;
> + case ADM_PATH_LIVE_REC:
> + route->matrix_id = ADM_MATRIX_ID_AUDIO_TX;
> + break;
> + default:
> + dev_err(dev, "Wrong path set[%d]\n", path);
> + break;
> + }
> +
> + node->session_id = payload_map.session_id;
> + node->num_copps = payload_map.num_copps;
> +
> + for (i = 0; i < payload_map.num_copps; i++) {
> + int port_idx = payload_map.port_id[i];
> +
> + if (port_idx < 0) {
> + dev_err(dev, "Invalid port_id 0x%x\n",
> + payload_map.port_id[i]);
> + kfree(pkt);
> + return -EINVAL;
> + }
> + copp_idx = payload_map.copp_idx[i];
> +
> + copp = adm_find_copp(adm, port_idx, copp_idx);
> + if (!copp) {
> + kfree(pkt);
> + return -EINVAL;
> + }
> +
> + copps_list[i] = copp->id;
> + }
> +
> + mutex_lock(&adm->lock);
> + adm->result.status = 0;
> + adm->result.opcode = 0;
> +
> + ret = apr_send_pkt(adm->apr, pkt);
> + if (ret < 0) {
> + dev_err(dev, "routing for syream %d failed ret %d\n",
"stream" typo
> + payload_map.session_id, ret);
> + goto fail_cmd;
> + }
> + ret = wait_event_timeout(adm->matrix_map_wait,
> + adm->result.opcode == pkt->hdr.opcode,
> + msecs_to_jiffies(TIMEOUT_MS));
> + if (!ret) {
> + dev_err(dev, "routing for stream %d failed\n",
> + payload_map.session_id);
> + ret = -ETIMEDOUT;
> + goto fail_cmd;
> + } else if (adm->result.status > 0) {
> + dev_err(dev, "DSP returned error[%d]\n",
> + adm->result.status);
> + ret = -EINVAL;
> + goto fail_cmd;
> + }
> +
> +fail_cmd:
> + mutex_unlock(&adm->lock);
> + kfree(pkt);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(q6adm_matrix_map);
> +
> +/**
> + * q6adm_close() - Close adm copp
> + *
> + * @dev: Pointer to adm child device.
> + * @port_id: afe port id.
> + * @perf_mode: perf_mode mode
> + * @copp_idx: copp index to close
> + *
> + * Return: Will be an negative on error or a zero on success.
> + */
> +int q6adm_close(struct device *dev, int port_id, int perf_mode, int copp_idx)
perf_mode unused param. Remove for now. Can be added back when needed.
Otherwise LGTM.
Once fixed above, add acked-by
Acked-by: Banajit Goswami <bgoswami@codeaurora.org>
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH v2 1/1] dts: qcom: db820c: Add gpio-line-names property
From: Todor Tomov @ 2018-05-09 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180418134601.8502-2-manivannan.sadhasivam@linaro.org>
Hi Mani,
On 18.04.2018 16:46, Manivannan Sadhasivam wrote:
> Add gpio-line-names property for Dragonboard820c based on APQ8096 SoC.
> There are 4 gpio-controllers present on this board, including the
> APQ8096 SoC, PM8994 (GPIO and MPP) and PMI8994 (GPIO).
>
> Lines names are derived from 96Boards CE Specification 1.0, Appendix
> "Expansion Connector Signal Description". Line names for PMI8994 MPP
> pins are not added due to the absence of the gpio-controller support.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Thank you for adding the schematic names to the comments.
You can have my:
Reviewed-by: Todor Tomov <todor.tomov@linaro.org>
> ---
> arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 239 +++++++++++++++++++++++++++
> 1 file changed, 239 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
> index 1c8f1b86472d..473530527e27 100644
> --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
> +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
> @@ -19,6 +19,33 @@
> #include <dt-bindings/input/input.h>
> #include <dt-bindings/gpio/gpio.h>
>
> +/*
> + * GPIO name legend: proper name = the GPIO line is used as GPIO
> + * NC = not connected (pin out but not routed from the chip to
> + * anything the board)
> + * "[PER]" = pin is muxed for [peripheral] (not GPIO)
> + * LSEC = Low Speed External Connector
> + * P HSEC = Primary High Speed External Connector
> + * S HSEC = Secondary High Speed External Connector
> + * J14 = Camera Connector
> + * TP = Test Points
> + *
> + * Line names are taken from the schematic "DragonBoard 820c",
> + * drawing no: LM25-P2751-1
> + *
> + * For the lines routed to the external connectors the
> + * lines are named after the 96Boards CE Specification 1.0,
> + * Appendix "Expansion Connector Signal Description".
> + *
> + * When the 96Board naming of a line and the schematic name of
> + * the same line are in conflict, the 96Board specification
> + * takes precedence, which means that the external UART on the
> + * LSEC is named UART0 while the schematic and SoC names this
> + * UART3. This is only for the informational lines i.e. "[FOO]",
> + * the GPIO named lines "GPIO-A" thru "GPIO-L" are the only
> + * ones actually used for GPIO.
> + */
> +
> / {
> aliases {
> serial0 = &blsp2_uart1;
> @@ -90,6 +117,218 @@
> status = "okay";
> };
>
> + pinctrl at 1010000 {
> + gpio-line-names =
> + "[SPI0_DOUT]", /* GPIO_0, BLSP1_SPI_MOSI, LSEC pin 14 */
> + "[SPI0_DIN]", /* GPIO_1, BLSP1_SPI_MISO, LSEC pin 10 */
> + "[SPI0_CS]", /* GPIO_2, BLSP1_SPI_CS_N, LSEC pin 12 */
> + "[SPI0_SCLK]", /* GPIO_3, BLSP1_SPI_CLK, LSEC pin 8 */
> + "[UART1_TxD]", /* GPIO_4, BLSP8_UART_TX, LSEC pin 11 */
> + "[UART1_RxD]", /* GPIO_5, BLSP8_UART_RX, LSEC pin 13 */
> + "[I2C1_SDA]", /* GPIO_6, BLSP8_I2C_SDA, LSEC pin 21 */
> + "[I2C1_SCL]", /* GPIO_7, BLSP8_I2C_SCL, LSEC pin 19 */
> + "GPIO-H", /* GPIO_8, LCD0_RESET_N, LSEC pin 30 */
> + "TP93", /* GPIO_9 */
> + "GPIO-G", /* GPIO_10, MDP_VSYNC_P, LSEC pin 29 */
> + "[MDP_VSYNC_S]", /* GPIO_11, S HSEC pin 55 */
> + "NC", /* GPIO_12 */
> + "[CSI0_MCLK]", /* GPIO_13, CAM_MCLK0, P HSEC pin 15 */
> + "[CAM_MCLK1]", /* GPIO_14, J14 pin 11 */
> + "[CSI1_MCLK]", /* GPIO_15, CAM_MCLK2, P HSEC pin 17 */
> + "TP99", /* GPIO_16 */
> + "[I2C2_SDA]", /* GPIO_17, CCI_I2C_SDA0, P HSEC pin 34 */
> + "[I2C2_SCL]", /* GPIO_18, CCI_I2C_SCL0, P HSEC pin 32 */
> + "[CCI_I2C_SDA1]", /* GPIO_19, S HSEC pin 38 */
> + "[CCI_I2C_SCL1]", /* GPIO_20, S HSEC pin 36 */
> + "FLASH_STROBE_EN", /* GPIO_21, S HSEC pin 5 */
> + "FLASH_STROBE_TRIG", /* GPIO_22, S HSEC pin 1 */
> + "GPIO-K", /* GPIO_23, CAM2_RST_N, LSEC pin 33 */
> + "GPIO-D", /* GPIO_24, LSEC pin 26 */
> + "GPIO-I", /* GPIO_25, CAM0_RST_N, LSEC pin 31 */
> + "GPIO-J", /* GPIO_26, CAM0_STANDBY_N, LSEC pin 32 */
> + "BLSP6_I2C_SDA", /* GPIO_27 */
> + "BLSP6_I2C_SCL", /* GPIO_28 */
> + "GPIO-B", /* GPIO_29, TS0_RESET_N, LSEC pin 24 */
> + "GPIO30", /* GPIO_30, S HSEC pin 4 */
> + "HDMI_CEC", /* GPIO_31 */
> + "HDMI_DDC_CLOCK", /* GPIO_32 */
> + "HDMI_DDC_DATA", /* GPIO_33 */
> + "HDMI_HOT_PLUG_DETECT", /* GPIO_34 */
> + "PCIE0_RST_N", /* GPIO_35 */
> + "PCIE0_CLKREQ_N", /* GPIO_36 */
> + "PCIE0_WAKE", /* GPIO_37 */
> + "SD_CARD_DET_N", /* GPIO_38 */
> + "TSIF1_SYNC", /* GPIO_39, S HSEC pin 48 */
> + "W_DISABLE_N", /* GPIO_40 */
> + "[BLSP9_UART_TX]", /* GPIO_41 */
> + "[BLSP9_UART_RX]", /* GPIO_42 */
> + "[BLSP2_UART_CTS_N]", /* GPIO_43 */
> + "[BLSP2_UART_RFR_N]", /* GPIO_44 */
> + "[BLSP3_UART_TX]", /* GPIO_45 */
> + "[BLSP3_UART_RX]", /* GPIO_46 */
> + "[I2C0_SDA]", /* GPIO_47, LS_I2C0_SDA, LSEC pin 17 */
> + "[I2C0_SCL]", /* GPIO_48, LS_I2C0_SCL, LSEC pin 15 */
> + "[UART0_TxD]", /* GPIO_49, BLSP9_UART_TX, LSEC pin 5 */
> + "[UART0_RxD]", /* GPIO_50, BLSP9_UART_RX, LSEC pin 7 */
> + "[UART0_CTS]", /* GPIO_51, BLSP9_UART_CTS_N, LSEC pin 3 */
> + "[UART0_RTS]", /* GPIO_52, BLSP9_UART_RFR_N, LSEC pin 9 */
> + "[CODEC_INT1_N]", /* GPIO_53 */
> + "[CODEC_INT2_N]", /* GPIO_54 */
> + "[BLSP7_I2C_SDA]", /* GPIO_55 */
> + "[BLSP7_I2C_SCL]", /* GPIO_56 */
> + "MI2S_MCLK", /* GPIO_57, S HSEC pin 3 */
> + "[PCM_CLK]", /* GPIO_58, QUA_MI2S_SCK, LSEC pin 18 */
> + "[PCM_FS]", /* GPIO_59, QUA_MI2S_WS, LSEC pin 16 */
> + "[PCM_DO]", /* GPIO_60, QUA_MI2S_DATA0, LSEC pin 20 */
> + "[PCM_DI]", /* GPIO_61, QUA_MI2S_DATA1, LSEC pin 22 */
> + "GPIO-E", /* GPIO_62, LSEC pin 27 */
> + "TP87", /* GPIO_63 */
> + "[CODEC_RST_N]", /* GPIO_64 */
> + "[PCM1_CLK]", /* GPIO_65 */
> + "[PCM1_SYNC]", /* GPIO_66 */
> + "[PCM1_DIN]", /* GPIO_67 */
> + "[PCM1_DOUT]", /* GPIO_68 */
> + "AUDIO_REF_CLK", /* GPIO_69 */
> + "SLIMBUS_CLK", /* GPIO_70 */
> + "SLIMBUS_DATA0", /* GPIO_71 */
> + "SLIMBUS_DATA1", /* GPIO_72 */
> + "NC", /* GPIO_73 */
> + "NC", /* GPIO_74 */
> + "NC", /* GPIO_75 */
> + "NC", /* GPIO_76 */
> + "TP94", /* GPIO_77 */
> + "NC", /* GPIO_78 */
> + "TP95", /* GPIO_79 */
> + "GPIO-A", /* GPIO_80, MEMS_RESET_N, LSEC pin 23 */
> + "TP88", /* GPIO_81 */
> + "TP89", /* GPIO_82 */
> + "TP90", /* GPIO_83 */
> + "TP91", /* GPIO_84 */
> + "[SD_DAT0]", /* GPIO_85, BLSP12_SPI_MOSI, P HSEC pin 1 */
> + "[SD_CMD]", /* GPIO_86, BLSP12_SPI_MISO, P HSEC pin 11 */
> + "[SD_DAT3]", /* GPIO_87, BLSP12_SPI_CS_N, P HSEC pin 7 */
> + "[SD_SCLK]", /* GPIO_88, BLSP12_SPI_CLK, P HSEC pin 9 */
> + "TSIF1_CLK", /* GPIO_89, S HSEC pin 42 */
> + "TSIF1_EN", /* GPIO_90, S HSEC pin 46 */
> + "TSIF1_DATA", /* GPIO_91, S HSEC pin 44 */
> + "NC", /* GPIO_92 */
> + "TSIF2_CLK", /* GPIO_93, S HSEC pin 52 */
> + "TSIF2_EN", /* GPIO_94, S HSEC pin 56 */
> + "TSIF2_DATA", /* GPIO_95, S HSEC pin 54 */
> + "TSIF2_SYNC", /* GPIO_96, S HSEC pin 58 */
> + "NC", /* GPIO_97 */
> + "CAM1_STANDBY_N", /* GPIO_98 */
> + "NC", /* GPIO_99 */
> + "NC", /* GPIO_100 */
> + "[LCD1_RESET_N]", /* GPIO_101, S HSEC pin 51 */
> + "BOOT_CONFIG1", /* GPIO_102 */
> + "USB_HUB_RESET", /* GPIO_103 */
> + "CAM1_RST_N", /* GPIO_104 */
> + "NC", /* GPIO_105 */
> + "NC", /* GPIO_106 */
> + "NC", /* GPIO_107 */
> + "NC", /* GPIO_108 */
> + "NC", /* GPIO_109 */
> + "NC", /* GPIO_110 */
> + "NC", /* GPIO_111 */
> + "NC", /* GPIO_112 */
> + "PMI8994_BUA", /* GPIO_113 */
> + "PCIE2_RST_N", /* GPIO_114 */
> + "PCIE2_CLKREQ_N", /* GPIO_115 */
> + "PCIE2_WAKE", /* GPIO_116 */
> + "SSC_IRQ_0", /* GPIO_117 */
> + "SSC_IRQ_1", /* GPIO_118 */
> + "SSC_IRQ_2", /* GPIO_119 */
> + "NC", /* GPIO_120 */
> + "GPIO121", /* GPIO_121, S HSEC pin 2 */
> + "NC", /* GPIO_122 */
> + "SSC_IRQ_6", /* GPIO_123 */
> + "SSC_IRQ_7", /* GPIO_124 */
> + "GPIO-C", /* GPIO_125, TS_INT0, LSEC pin 25 */
> + "BOOT_CONFIG5", /* GPIO_126 */
> + "NC", /* GPIO_127 */
> + "NC", /* GPIO_128 */
> + "BOOT_CONFIG7", /* GPIO_129 */
> + "PCIE1_RST_N", /* GPIO_130 */
> + "PCIE1_CLKREQ_N", /* GPIO_131 */
> + "PCIE1_WAKE", /* GPIO_132 */
> + "GPIO-L", /* GPIO_133, CAM2_STANDBY_N, LSEC pin 34 */
> + "NC", /* GPIO_134 */
> + "NC", /* GPIO_135 */
> + "BOOT_CONFIG8", /* GPIO_136 */
> + "NC", /* GPIO_137 */
> + "NC", /* GPIO_138 */
> + "GPS_SSBI2", /* GPIO_139 */
> + "GPS_SSBI1", /* GPIO_140 */
> + "NC", /* GPIO_141 */
> + "NC", /* GPIO_142 */
> + "NC", /* GPIO_143 */
> + "BOOT_CONFIG6", /* GPIO_144 */
> + "NC", /* GPIO_145 */
> + "NC", /* GPIO_146 */
> + "NC", /* GPIO_147 */
> + "NC", /* GPIO_148 */
> + "NC"; /* GPIO_149 */
> + };
> +
> + qcom,spmi at 400f000 {
> + pmic at 0 {
> + gpios at c000 {
> + gpio-line-names =
> + "NC",
> + "KEY_VOLP_N",
> + "NC",
> + "BL1_PWM",
> + "GPIO-F", /* BL0_PWM, LSEC pin 28 */
> + "BL1_EN",
> + "NC",
> + "WLAN_EN",
> + "NC",
> + "NC",
> + "NC",
> + "NC",
> + "NC",
> + "NC",
> + "DIVCLK1",
> + "DIVCLK2",
> + "DIVCLK3",
> + "DIVCLK4",
> + "BT_EN",
> + "PMIC_SLB",
> + "PMIC_BUA",
> + "USB_VBUS_DET";
> + };
> +
> + mpps at a000 {
> + gpio-line-names =
> + "VDDPX_BIAS",
> + "WIFI_LED",
> + "NC",
> + "BT_LED",
> + "PM_MPP05",
> + "PM_MPP06",
> + "PM_MPP07",
> + "NC";
> + };
> + };
> +
> + pmic at 2 {
> + gpios at c000 {
> + gpio-line-names =
> + "NC",
> + "SPKR_AMP_EN1",
> + "SPKR_AMP_EN2",
> + "TP61",
> + "NC",
> + "USB2_VBUS_DET",
> + "NC",
> + "NC",
> + "NC",
> + "NC";
> + };
> + };
> + };
> +
> phy at 34000 {
> status = "okay";
> };
>
--
Best regards,
Todor Tomov
^ permalink raw reply
* [PATCH] arm64: remove no-op macro VMLINUX_SYMBOL()
From: Masahiro Yamada @ 2018-05-09 7:46 UTC (permalink / raw)
To: linux-arm-kernel
VMLINUX_SYMBOL() is no-op unless CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
is defined. It has ever been selected only by BLACKFIN and METAG.
VMLINUX_SYMBOL() is unneeded for ARM64-specific code.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
arch/arm64/kernel/vmlinux.lds.S | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 0221aca..605d1b6 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -34,25 +34,25 @@ jiffies = jiffies_64;
* 4 KB (see related ASSERT() below) \
*/ \
. = ALIGN(SZ_4K); \
- VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \
+ __hyp_idmap_text_start = .; \
*(.hyp.idmap.text) \
- VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; \
- VMLINUX_SYMBOL(__hyp_text_start) = .; \
+ __hyp_idmap_text_end = .; \
+ __hyp_text_start = .; \
*(.hyp.text) \
- VMLINUX_SYMBOL(__hyp_text_end) = .;
+ __hyp_text_end = .;
#define IDMAP_TEXT \
. = ALIGN(SZ_4K); \
- VMLINUX_SYMBOL(__idmap_text_start) = .; \
+ __idmap_text_start = .; \
*(.idmap.text) \
- VMLINUX_SYMBOL(__idmap_text_end) = .;
+ __idmap_text_end = .;
#ifdef CONFIG_HIBERNATION
#define HIBERNATE_TEXT \
. = ALIGN(SZ_4K); \
- VMLINUX_SYMBOL(__hibernate_exit_text_start) = .;\
+ __hibernate_exit_text_start = .; \
*(.hibernate_exit.text) \
- VMLINUX_SYMBOL(__hibernate_exit_text_end) = .;
+ __hibernate_exit_text_end = .;
#else
#define HIBERNATE_TEXT
#endif
@@ -60,10 +60,10 @@ jiffies = jiffies_64;
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
#define TRAMP_TEXT \
. = ALIGN(PAGE_SIZE); \
- VMLINUX_SYMBOL(__entry_tramp_text_start) = .; \
+ __entry_tramp_text_start = .; \
*(.entry.tramp.text) \
. = ALIGN(PAGE_SIZE); \
- VMLINUX_SYMBOL(__entry_tramp_text_end) = .;
+ __entry_tramp_text_end = .;
#else
#define TRAMP_TEXT
#endif
--
2.7.4
^ permalink raw reply related
* [PATCH 1/5] dt-bindings: pinctrl: document the STMFX pinctrl bindings
From: Amelie DELAUNAY @ 2018-05-09 7:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180416181940.4b5z4svbde3ompij@rob-hp-laptop>
On 04/16/2018 08:19 PM, Rob Herring wrote:
> On Wed, Apr 11, 2018 at 11:47:01AM +0200, Amelie Delaunay wrote:
>> This patch adds documentation of device tree bindings for the
>> STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander.
>>
>> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
>> ---
>> .../devicetree/bindings/pinctrl/pinctrl-stmfx.txt | 118 +++++++++++++++++++++
>> 1 file changed, 118 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-stmfx.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-stmfx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-stmfx.txt
>> new file mode 100644
>> index 0000000..4d8941de
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-stmfx.txt
>> @@ -0,0 +1,118 @@
>> +STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander bindings
>> +
>> +ST Multi-Function eXpander (STMFX) is a slave controller using I2C for
>> +communication with the main MCU. It offers up to 24 GPIOs expansion.
>> +
>> +Required properties:
>> +- compatible: should be "st,stmfx-0300".
>> +- reg: I2C slave address of the device.
>> +- interrupt-parent: phandle of the STMFX parent interrupt controller.
>> +- interrutps: interrupt specifier triggered by MFX_IRQ_OUT signal.
>> +
>> +Optional property:
>
> s/property/properties/
>
>> +- drive-open-drain: configure MFX_IRQ_OUT as open drain.
>> +- vdd-supply: phandle of the regulator supplying STMFX.
>> +
>> +Required properties for gpio controller sub-node:
>> +- #gpio-cells: should be <2>, the first cell is the GPIO number and the second
>> + cell is the gpio flags in accordance with <dt-bindings/gpio/gpio.h>.
>> +- gpio-controller: marks the device as a GPIO controller.
>> +Please refer to ../gpio/gpio.txt.
>> +
>> +Optional properties for gpio controller sub-node:
>> +- #interrupt-cells: should be <2>, the first cell is the GPIO number and the
>> + second cell is the interrupt flags in accordance with
>> + <dt-bindings/interrupt-controller/irq.h>.
>> +- interrupt-controller: marks the device as an interrupt controller.
>> +
>> +Please refer to pinctrl-bindings.txt for pin configuration.
>> +
>> +Required properties for pin configuration sub-nodes:
>> +- pins: list of pins to which the configuration applies.
>> +
>> +Optional properties for pin configuration sub-nodes (pinconf-generic ones):
>> +- bias-disable: disable any bias on the pin.
>> +- bias-pull-up: the pin will be pulled up.
>> +- bias-pull-pin-default: use the pin-default pull state.
>> +- bias-pull-down: the pin will be pulled down.
>> +- drive-open-drain: the pin will be driven with open drain.
>> +- drive-push-pull: the pin will be driven actively high and low.
>> +- output-high: the pin will be configured as an output driving high level.
>> +- output-low: the pin will be configured as an output driving low level.
>> +
>> +Note that STMFX pins[15:0] are called "gpio[15:0]", and STMFX pins[23:16] are
>> +called "agpio[7:0]". Example, to refer to pin 18 of STMFX, use "agpio2".
>> +
>> +Example:
>> +
>> + stmfxpinctrl: stmfx at 42 {
>> + compatible = "st,stmfx-0300";
>> + reg = <0x42>;
>> + interrupt-parent = <&gpioi>;
>> + interrupts = <8 IRQ_TYPE_EDGE_RISING>;
>> + vdd-supply = <&v3v3>;
>> + status = "okay";
>
> Don't show status in examples.
>
I'll fix it.
>> +
>> + stmfxgpio: gpio {
>
> Why does this need to be a sub node? Are there functions beyond GPIO?
>
I'll address this point in my response to Linus.
>> + #gpio-cells = <2>;
>> + #interrupt-cells = <2>;
>> + gpio-controller;
>> + interrupt-controller;
>> + status = "okay";
>> + };
>> +
>> + joystick_pins: joystick at 0 {
>
> A unit-address without a reg prop is not valid.
>
OK, I'll replace it by 'joystick_pins: joystick-0'.
>> + pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
>> + drive-push-pull;
>> + bias-pull-down;
>> + };
>> + };
>> +
>> + joystick {
>> + compatible = "gpio-keys";
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + pinctrl-0 = <&joystick_pins>;
>> + pinctrl-names = "default";
>> + button at 0 {
>> + label = "JoySel";
>> + linux,code = <KEY_ENTER>;
>> + interrupt-parent = <&stmfxgpio>;
>> + interrupts = <0 IRQ_TYPE_EDGE_RISING>;
>> + };
>> + button at 1 {
>> + label = "JoyDown";
>> + linux,code = <KEY_DOWN>;
>> + interrupt-parent = <&stmfxgpio>;
>> + interrupts = <1 IRQ_TYPE_EDGE_RISING>;
>> + };
>> + button at 2 {
>> + label = "JoyLeft";
>> + linux,code = <KEY_LEFT>;
>> + interrupt-parent = <&stmfxgpio>;
>> + interrupts = <2 IRQ_TYPE_EDGE_RISING>;
>> + };
>> + button at 3 {
>> + label = "JoyRight";
>> + linux,code = <KEY_RIGHT>;
>> + interrupt-parent = <&stmfxgpio>;
>> + interrupts = <3 IRQ_TYPE_EDGE_RISING>;
>> + };
>> + button at 4 {
>> + label = "JoyUp";
>> + linux,code = <KEY_UP>;
>> + interrupt-parent = <&stmfxgpio>;
>> + interrupts = <4 IRQ_TYPE_EDGE_RISING>;
>> + };
>> + };
>> +
>> + leds {
>> + compatible = "gpio-leds";
>> + orange {
>> + gpios = <&stmfxgpio 17 1>;
>> + };
>> +
>> + blue {
>> + gpios = <&stmfxgpio 19 1>;
>> + };
>> + }
>> --
>> 2.7.4
>>
Thanks,
Amelie
^ permalink raw reply
* [PATCH] ARM: remove no-op macro VMLINUX_SYMBOL()
From: Masahiro Yamada @ 2018-05-09 7:30 UTC (permalink / raw)
To: linux-arm-kernel
VMLINUX_SYMBOL() is no-op unless CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
is defined. It has ever been selected only by BLACKFIN and METAG.
VMLINUX_SYMBOL() is unneeded for ARM-specific code.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
I will put this patch into Russell's patch tracker.
This is for reviewing.
arch/arm/kernel/vmlinux.lds.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm/kernel/vmlinux.lds.h b/arch/arm/kernel/vmlinux.lds.h
index 71281e0..ae5fdff 100644
--- a/arch/arm/kernel/vmlinux.lds.h
+++ b/arch/arm/kernel/vmlinux.lds.h
@@ -27,24 +27,24 @@
#define PROC_INFO \
. = ALIGN(4); \
- VMLINUX_SYMBOL(__proc_info_begin) = .; \
+ __proc_info_begin = .; \
*(.proc.info.init) \
- VMLINUX_SYMBOL(__proc_info_end) = .;
+ __proc_info_end = .;
#define HYPERVISOR_TEXT \
- VMLINUX_SYMBOL(__hyp_text_start) = .; \
+ __hyp_text_start = .; \
*(.hyp.text) \
- VMLINUX_SYMBOL(__hyp_text_end) = .;
+ __hyp_text_end = .;
#define IDMAP_TEXT \
ALIGN_FUNCTION(); \
- VMLINUX_SYMBOL(__idmap_text_start) = .; \
+ __idmap_text_start = .; \
*(.idmap.text) \
- VMLINUX_SYMBOL(__idmap_text_end) = .; \
+ __idmap_text_end = .; \
. = ALIGN(PAGE_SIZE); \
- VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \
+ __hyp_idmap_text_start = .; \
*(.hyp.idmap.text) \
- VMLINUX_SYMBOL(__hyp_idmap_text_end) = .;
+ __hyp_idmap_text_end = .;
#define ARM_DISCARD \
*(.ARM.exidx.exit.text) \
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
From: Amelie DELAUNAY @ 2018-05-09 7:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180427030140.nmlqmpewqatabnmt@rob-hp-laptop>
On 04/27/2018 05:01 AM, Rob Herring wrote:
> On Thu, Apr 19, 2018 at 03:34:04PM +0200, Amelie Delaunay wrote:
>> RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
>> doesn't require to disable backup domain write protection, and rtc_ck
>> parent clock assignment isn't allowed.
>> To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
>> alarm interrupt.
>>
>> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
>> ---
>> .../devicetree/bindings/rtc/st,stm32-rtc.txt | 27 +++++++++++++++++-----
>> 1 file changed, 21 insertions(+), 6 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> index 00f8b5d..f1c2080 100644
>> --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> @@ -1,25 +1,31 @@
>> STM32 Real Time Clock
>>
>> Required properties:
>> -- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
>> - the device is compatible with stm32(f4/f7) or stm32h7.
>> +- compatible: can be "st,stm32-rtc", "st,stm32h7-rtc" or "st,stm32mp1-rtc",
>> + depending on the device is compatible with stm32(f4/f7), stm32h7
>> + or stm32mp1.
>
> One compatible per line please.
>
>> - reg: address range of rtc register set.
>> - clocks: can use up to two clocks, depending on part used:
>> - "rtc_ck": RTC clock source.
>> - It is required on stm32(f4/f7) and stm32h7.
>> + It is required on stm32(f4/f7/h7/mp1).
>
> IOW, required for all?
>
Yes, so, I'll remove the comment as it is required for all.
>> - "pclk": RTC APB interface clock.
>> It is not present on stm32(f4/f7).
>> - It is required on stm32h7.
>> + It is required on stm32(h7/mp1).
>> - clock-names: must be "rtc_ck" and "pclk".
>> - It is required only on stm32h7.
>> + It is required on stm32(h7/mp1).
>> - interrupt-parent: phandle for the interrupt controller.
>> + It is required on stm32(f4/f7/h7).
>> - interrupts: rtc alarm interrupt.
>> +- interrupts-extended: replace interrupts property on stm32mp1, to specify rtc
>> + alarm wakeup interrupt, which is on exti interrupt controller instead of gic.
>> + It is required on stm32mp1.
>
> Just document 'interrupts'. interrupts-extended is implicitly supported
> and what the interrupts are connected to is outside the scope of this
> binding.
>
OK, I'll clean this.
>> - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
>> access control register at offset, and change the dbp (Disable Backup
>> Protection) bit represented by the mask, mandatory to disable/enable backup
>> domain (RTC registers) write protection.
>> + It is required on stm32(f4/f7/h7).
>>
>> -Optional properties (to override default rtc_ck parent clock):
>> +Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
>> - assigned-clocks: reference to the rtc_ck clock entry.
>> - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
>>
>> @@ -48,3 +54,12 @@ Example:
>> interrupt-names = "alarm";
>> st,syscfg = <&pwrcfg 0x00 0x100>;
>> };
>> +
>> + rtc: rtc at 5c004000 {
>> + compatible = "st,stm32mp1-rtc";
>> + reg = <0x5c004000 0x400>;
>> + clocks = <&rcc RTCAPB>, <&rcc RTC>;
>> + clock-names = "pclk", "rtc_ck";
>> + interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
>> + <&exti 19 1>;
>> + };
>> --
>> 2.7.4
>>
Thanks,
Amelie
^ permalink raw reply
* [PATCH 3/4] dt-bindings: rtc: update stm32-rtc documentation for st,syscfg property
From: Amelie DELAUNAY @ 2018-05-09 7:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <a2cbe252-c957-103d-aae1-4a8fce9116fa@st.com>
Hi,
On 05/04/2018 09:40 AM, Alexandre Torgue wrote:
> Hi Alexandre,
>
> On 05/03/2018 10:53 PM, Alexandre Belloni wrote:
>> Amelie,
>>
>> On 26/04/2018 21:58:03-0500, Rob Herring wrote:
>>> On Thu, Apr 19, 2018 at 03:21:42PM +0200, Amelie Delaunay wrote:
>>>> RTC driver should not be aware of the PWR registers offset and bits
>>>> position. Furthermore, we can imagine that Disable Backup Protection
>>>> (DBP)
>>>> relative register and bit mask could change depending on the SoC. So
>>>> this
>>>> patch moves st,syscfg property from single pwrcfg phandle to pwrcfg
>>>> phandle/offset/mask triplet.
>>>>
>>>> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
>>>> ---
>>>> ? Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt | 10
>>>> ++++++----
>>>> ? 1 file changed, 6 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>>>> b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>>>> index a66692a..00f8b5d 100644
>>>> --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>>>> +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>>>> @@ -14,8 +14,10 @@ Required properties:
>>>> ????? It is required only on stm32h7.
>>>> ? - interrupt-parent: phandle for the interrupt controller.
>>>> ? - interrupts: rtc alarm interrupt.
>>>> -- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup
>>>> domain
>>>> -? (RTC registers) write protection.
>>>> +- st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg
>>>> used to
>>>> +? access control register at offset, and change the dbp (Disable
>>>> Backup
>>>> +? Protection) bit represented by the mask, mandatory to
>>>> disable/enable backup
>>>> +? domain (RTC registers) write protection.
>>>
>>> It's fine to add this, but you are breaking compatibility in the driver
>>> with existing DTBs by requiring these new fields.
>>>
>>
>> I'm fine with that change but I would like confirmation that this has
>> been well thought. Maybe Maxime or Alexandre could give their ack.
>>
>
> It's a good thing to remove PWR registers information from RTC driver.
> My only concern was the compatibility with old DT but we can accept it.
> Indeed, Kernel will continue to boot fine, only RTC will not probe if we
> use old DT.
>
> Acked-by: Alexandre TORGUE <alexandre.torgue@st.com>
>
> Regards
> alex
I am going to send a series to update st,syscfg property in
stm32f429/stm32f746/stm32h743 RTC node.
Thanks,
Amelie
^ permalink raw reply
* [PATCH v4 1/3] drm/panel: Add RGB666 variant of Innolux AT070TN90
From: Maxime Ripard @ 2018-05-09 7:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180507220413.21990-1-contact@paulk.fr>
On Tue, May 08, 2018 at 12:04:11AM +0200, Paul Kocialkowski wrote:
> This adds timings for the RGB666 variant of the Innolux AT070TN90 panel,
> as found on the Ainol AW1 tablet.
>
> The panel also supports RGB888 output. When RGB666 mode is used instead,
> the two extra lanes per component are grounded.
>
> In the future, it might become necessary to introduce a dedicated
> device-tree property to specify the bus format to use instead of the
> default one for the panel. This will allow supporting different bus
> formats for the same panel modes.
>
> Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
> ---
> drivers/gpu/drm/panel/panel-simple.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index cbf1ab404ee7..32e30d5a8f08 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -1063,6 +1063,29 @@ static const struct panel_desc innolux_at043tn24 = {
> .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
> };
>
> +static const struct drm_display_mode innolux_at070tn90_mode = {
> + .clock = 40000,
> + .hdisplay = 800,
> + .hsync_start = 800 + 112,
> + .hsync_end = 800 + 112 + 1,
> + .htotal = 800 + 112 + 1 + 87,
> + .vdisplay = 480,
> + .vsync_start = 480 + 141,
> + .vsync_end = 480 + 141 + 1,
> + .vtotal = 480 + 141 + 1 + 38,
> + .vrefresh = 60,
> +};
> +
> +static const struct panel_desc innolux_at070tn90 = {
> + .modes = &innolux_at070tn90_mode,
> + .num_modes = 1,
> + .size = {
> + .width = 154,
> + .height = 86,
> + },
> + .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
> +};
> +
I'm not really convinced this is the right approach. You said it
yourself, the panel is using a 24-bits interface, and you just happen
to have a tablet that routed it using a 18-bits interface instead.
That doesn't belong in the driver, especially associated to the
compatible, but where the routing is described: in the device
tree. And given that the panel interface is a 24 bits panel, if we
were to have a default, we should have this one, and not the one
fitting your use case.
Maxime
--
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180509/e968d33b/attachment.sig>
^ permalink raw reply
* [PATCH v9 00/12] Sunxi: Add SMP support on A83T
From: Maxime Ripard @ 2018-05-09 7:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7491f58f-d24d-8f7c-c195-87d13457fd80@gmail.com>
Hi!
On Tue, May 08, 2018 at 10:11:07AM -0700, Florian Fainelli wrote:
> On 05/08/2018 06:19 AM, Maxime Ripard wrote:
> > Hi,
> >
> > On Fri, May 04, 2018 at 09:05:33PM +0200, Myl?ne Josserand wrote:
> >> Hello everyone,
> >>
> >> This is a V9 of my series that adds SMP support for Allwinner sun8i-a83t.
> >> Based on sunxi's tree, sunxi/for-next branch.
> >> Depends on a patch from Doug Berger that allows to include the "cpu-type"
> >> header on assembly files that I included in my series (patch 01).
> >
> > I applied the patches, with the remarks done by Russell on v8 fixed,
> > and the function sun8i_a83t_cntvoff_init made static.
>
> Did you push those patches to sunxi/linux.git yet? I would like to make
> sure I have the same copy of patch 1 since that is necessary for some of
> our Broadcom ARM SoCs for 4.18.
I forgot, I just did. I tested to merge the latest next tag though,
and it went fine without any conflicts, so I guess we're fine?
Maxime
--
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180509/3ef6b223/attachment.sig>
^ permalink raw reply
* [RESEND PATCH] pinctrl: rockchip: Disable interrupt when changing it's capability
From: JeffyChen @ 2018-05-09 6:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAD=FV=WZ+2MNbe341M7OQD11+RxaJuzdM6zMnXYB4dka74K1hQ@mail.gmail.com>
Hi Doug,
Thanks for your reply :)
On 05/09/2018 01:18 PM, Doug Anderson wrote:
>> >
>> >
>> >right, so we now have 2 cases: rockchip_irq_demux/ rockchip_irq_set_type
>> >
>> >if i'm right about the spurious irq(only happen when set rising for a high
>> >gpio, or set falling for a low gpio), then:
>> >
>> >1/ rockchip_irq_demux
>> >it's important to not losing irqs in this case, maybe we can
>> >
>> >a) ack irq
>> >b) update polarity for edge both irq
>> >
>> >we don't need to disable irq in b), since we would not hit the spurious irq
>> >cases here(always check gpio level to toggle it)
> Unless you have some sort of proof that rockchip_irq_demux(), I would
> take it as an example of something that works. I remember stress
> testing the heck out of it. Do you have some evidence that it's not
> working? I think Brian was simply speculating that there might be a
> race here, but I don't think anyone has shown it have they? Looking
> back at my notes, the thing I really made sure to stress was that we
> never got into a situation where we were losing an edge (AKA we were
> never configured to look for a falling edge when the line was already
> low). I'm not sure I confirmed that we never got an extra interrupt.
>
> I'm at home right now and I can't add prints and poke at things, but
> as I understand it for edge interrupts the usual flow to make sure
> interrupts aren't ever lost is:
>
> 1. See that the interrupt went off
> 2. Ack it (clear it)
> 3. Call the interrupt handler
>
> ...presumably in this case rockchip_irq_demux() is called after step
> #2 (but I don't know if it's called before or after step #3). If the
> line is toggling like crazy while the 3 steps are going on, it's OK if
> the interrupt handler is called more than once. In general this could
> be considered expected. That's why you Ack before handling--any extra
> edges that come in any time after the interrupt handler starts (even
> after the very first instruction) need to cause the interrupt handler
> to get called again.
>
> This is different than Brian's understanding since he seemed to think
> the Ack was happening later. If you're in front of something where
> you can add printouts, maybe you can tell us. I tried to look through
> the code and it was too twisted for me to be sure.
i think the current edge both irq flow for rk3399 would be:
gic_handle_irq //irq-gic-v3.c
handle_domain_irq
rockchip_irq_demux //pinctrl-rockchip.c
toggle polarity
generic_handle_irq
handle_edge_irq //kernel/irq
irq_ack
handle_irq_event
action->handler
so i think the race might actually exist (maybe we can add some delay
after toggle polarity to confirm)
BTW, checking other drivers, there're quite a few using this kind of
toggle edge for edge both, and they go different ways:
1/ toggle it in ack():
mediatek/pinctrl-mtk-common.c
gpio-ingenic.c
gpio-ep93xx.c
2/ toggle it before handle_irq:
pinctrl-rockchip.c
pinctrl-armada-37xx.c
gpio-ath79.c
gpio-mxs.c
gpio-omap.c
gpio-mvebu.c
3/ toggle it after handle_irq:
gpio-dwapb.c
gpio-pmic-eic-sprd.c
would it make sense to support this kind of emulate edge both irq in
some core codes?
>
>
>> >2/ rockchip_irq_set_type
>> >it's important to not having spurious irqs
>> >
>> >so we can disable irq during changing polarity only in these case:
>> >((rising && gpio is heigh) || (falling && gpio is low))
>> >
>> >i'm still confirming the spurious irq with IC guys.
> Hmmm, thinking about all this more, I'm curious how callers expect
> this to work. Certainly things are undefined if you have the
> following situation:
>
> Start: rising edge trigger, line is actually high
> Request: change to falling edge trigger
> Line falls during the request
>
> In that case it's OK to throw the interrupt away because it can be
> argued that the line could have fallen before the request actually
> took place. ...but it seems like there could be situations where the
> user wouldn't expect interrupts to be thrown away by a call to
> irq_set_type(). In other words:
>
> Start: rising edge trigger, line is actually high
> Request: change to falling edge trigger
> Line falls, rises, and falls during the request
>
> ...in that case you'd expect that some sort of interrupt would have
> gone off and not be thrown away. No matter what instant in time the
> request actually took place it should have caught an edge, right?
>
>
> Said another way: As a client of irq_set_type() I'd expect it to not
> throw away interrupts, but I'd expect that the change in type would be
> atomic. That is: if the interrupt came in before the type change in
> type applied then it should trigger with the old rules. If the
> interrupt came in after the type change then it should trigger with
> the new rules.
>
>
> I would be tempted to confirm your testing and just clear the spurious
> interrupts that you're aware of. AKA: if there's no interrupt pending
> and you change the type to "IRQ_TYPE_EDGE_RISING" or
> "IRQ_TYPE_EDGE_FALLING" then you should clear the interrupt. It's
> still racy, but I guess it's the best you can do unless IC guys come
> up with something better.
>
hmmm, right, clear the spurious irq seems to be a better way, will try
to do it in the next version.
>
>
> Anyway, it's past my bedtime. Hopefully some of the above made sense.
> I'm sure you'll tell me if it didn't or if I said something
> stupid/wrong.:-P
>
> -Doug
>
>
>
^ permalink raw reply
* [PATCH] Kirin-PCIe: Add kirin pcie msi feature.
From: Yao Chen @ 2018-05-09 6:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180508125658.GK161390@bhelgaas-glaptop.roam.corp.google.com>
On 2018/5/8 20:56, Bjorn Helgaas wrote:
> [+cc Stanimir, Jianguo, Shawn for qcom, histb comments below]
>
> On Tue, May 08, 2018 at 03:03:48PM +0800, Yao Chen wrote:
>> This patch adds kirin pcie msi feature.
>
> Thanks for the patch! Please update your subject and changelog like this:
>
> PCI: kirin: Add MSI support
>
> Add support for MSI.
>
> You can figure out what style to use for the subject by running:
>
> git log --oneline drivers/pci/dwc/pcie-kirin.c
>
> Then follow the existing style.
>
Ok, I will update the style of subject and changelog.
>> Signed-off-by: Yao Chen <chenyao11@huawei.com>
>> ---
>> arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 2 ++
>> drivers/pci/dwc/pcie-kirin.c | 38 +++++++++++++++++++++++++++++++
>> 2 files changed, 40 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
>> index ec3eb8e..4ef684f 100644
>> --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
>> +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
>> @@ -872,6 +872,8 @@
>> 0x0 0x02000000>;
>> num-lanes = <1>;
>> #interrupt-cells = <1>;
>> + interrupts = <0 283 4>;
>> + interrupts-names = "msi";
>> interrupt-map-mask = <0xf800 0 0 7>;
>> interrupt-map = <0x0 0 0 1
>> &gic GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
>> diff --git a/drivers/pci/dwc/pcie-kirin.c b/drivers/pci/dwc/pcie-kirin.c
>> index d2970a0..2319c9c 100644
>> --- a/drivers/pci/dwc/pcie-kirin.c
>> +++ b/drivers/pci/dwc/pcie-kirin.c
>> @@ -426,9 +426,28 @@ static int kirin_pcie_establish_link(struct pcie_port *pp)
>> return 0;
>> }
>>
>> +static irqreturn_t kirin_pcie_msi_irq_handler(int irq, void *arg)
>> +{
>> + struct pcie_port *pp = arg;
>> +
>> + return dw_handle_msi_irq(pp);
>> +}
>> +
>> +static void kirin_pcie_msi_init(struct pcie_port *pp)
>> +{
>> + dw_pcie_msi_init(pp);
>> +}
>> +
>> +static void kirin_pcie_enable_interrupts(struct pcie_port *pp)
>> +{
>> + if (IS_ENABLED(CONFIG_PCI_MSI))
>> + kirin_pcie_msi_init(pp);
>> +}
>> +
>> static int kirin_pcie_host_init(struct pcie_port *pp)
>> {
>> kirin_pcie_establish_link(pp);
>> + kirin_pcie_enable_interrupts(pp);
>>
>> return 0;
>> }
>> @@ -448,6 +467,25 @@ static int kirin_pcie_host_init(struct pcie_port *pp)
>> static int __init kirin_add_pcie_port(struct dw_pcie *pci,
>> struct platform_device *pdev)
>> {
>> + int ret;
>> +
>> + if (IS_ENABLED(CONFIG_PCI_MSI)) {
>> + pci->pp.msi_irq = platform_get_irq(pdev, 0);
>> + if (!pci->pp.msi_irq) {
>> + dev_err(&pdev->dev, "failed to get msi irq\n");
>
> s/msi irq/MSI IRQ/
>
>> + return -ENODEV;
>> + }
>> + ret = devm_request_irq(&pdev->dev, pci->pp.msi_irq,
>> + kirin_pcie_msi_irq_handler,
>> + IRQF_SHARED | IRQF_NO_THREAD,
>> + "kirin_pcie_msi", &pci->pp);
>> + if (ret) {
>> + dev_err(&pdev->dev, "failed to request msi irq\n");
>
> s/msi irq/MSI IRQ/
> Also, please include the IRQ number (pci->pp.msi_irq) in the message.
>
Ok, I will add msi_irq message.
>> + return ret;
>> + }
>> + }
>> +
>> + pci->pp.root_bus_nr = -1;
>
> Setting root_bus_nr looks like an unrelated change that should be in a
> separate patch.
>
> But I'm not sure why you need to set root_bus_nr at all, since
> dw_pcie_host_init() always sets it.
>
> Some other callers of dw_pcie_host_init() do set it:
>
> exynos_add_pcie_port()
> imx6_add_pcie_port()
> armada8k_add_pcie_port()
> artpec6_add_pcie_port()
> dw_plat_add_pcie_port()
> histb_pcie_probe()
> qcom_pcie_probe()
> spear13xx_add_pcie_port()
>
> But I don't see *why* any of these need to set it. If they don't need to
> set it, they shouldn't.
>
> And it would be nice if histb and qcom followed the structure and naming
> conventions of the other drivers, i.e., they should have
> histb_add_pcie_port() and qcom_add_pcie_port().
>
You're right, "pci->pp.root_bus_nr = -1;" is truly unnecessary. I will delete it.
>> pci->pp.ops = &kirin_pcie_host_ops;
>>
>> return dw_pcie_host_init(&pci->pp);
>> --
>> 1.9.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> .
>
Thanks,
Yao
^ permalink raw reply
* [PATCH v7 08/24] ASoC: qdsp6: q6core: Add q6core driver
From: Srinivas Kandagatla @ 2018-05-09 6:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <46511158-ed1d-7f07-0a8f-b325c088e386@codeaurora.org>
Thanks Banajit for the review!
On 04/05/18 20:04, Banajit Goswami wrote:
>> +
>> +static int q6core_callback(struct apr_device *adev, struct
>> apr_resp_pkt *data)
>> +{
>> + struct q6core *core = dev_get_drvdata(&adev->dev);
>> + struct aprv2_ibasic_rsp_result_t *result;
>> + struct apr_hdr *hdr = &data->hdr;
>> +
>> + result = data->payload;
>> + switch (hdr->opcode) {
>> + case APR_BASIC_RSP_RESULT:{
>> + result = data->payload;
>> + switch (result->opcode) {
>> + case AVCS_GET_VERSIONS:
>> + if (result->status == ADSP_EUNSUPPORTED)
>> + core->get_version_supported = false;
>> + core->resp_received = true;
>> + break;
>> + case AVCS_CMD_GET_FWK_VERSION:
>> + if (result->status == ADSP_EUNSUPPORTED)
>> + core->fwk_version_supported = false;
>> + core->resp_received = true;
>> + break;
>> + case AVCS_CMD_ADSP_EVENT_GET_STATE:
>> + if (result->status == ADSP_EUNSUPPORTED)
>> + core->get_state_supported = false;
>> + core->resp_received = true;
>> + break;
>> + }
>> + break;
>> + }
>> + case AVCS_CMDRSP_GET_FWK_VERSION: {
>> + struct avcs_cmdrsp_get_fwk_version *fwk;
>> + int bytes;
>> +
>> + fwk = data->payload;
>> + core->fwk_version_supported = true;
>> + bytes = sizeof(*fwk) + fwk->num_services *
>> + sizeof(fwk->svc_api_info[0]);
>> +
>> + core->fwk_version = kzalloc(bytes, GFP_ATOMIC);
>> + if (!core->fwk_version)
>> + return -ENOMEM;
> When the above allocation fails, core->fwk_version_supported will be
> still true, and q6core_get_fwk_versions() will return 0 (timeout as
> core->resp_received will not be set to true). This can cause a NULL
> pointer dereference inside the if() loop pointed below (added comment).
> Please move the line to set core->fwk_version_supported flag to after
> memset() to copy fwk version info.
Yes, makes sense, I fixed this and other comments in v8.
thanks,
srini
>> +
>> + memcpy(core->fwk_version, data->payload, bytes);
>> +
>> + core->resp_received = true;
>> +
>> + break;
>> + }
>> + case AVCS_GET_VERSIONS_RSP: {
>> + struct avcs_cmdrsp_get_version *v;
>> + int len;
>> +
>> + v = data->payload;
>> + core->get_version_supported = true;
>> +
^ permalink raw reply
* [PATCH v7 11/24] ASoC: qdsp6: q6afe: Add support to MI2S ports
From: Srinivas Kandagatla @ 2018-05-09 6:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2d1e7dfd-b65a-4297-f98b-15c2dd54c61a@codeaurora.org>
Thanks Banajit for review!
On 09/05/18 04:21, Banajit Goswami wrote:
>
> On 5/1/2018 5:08 AM, Srinivas Kandagatla wrote:
>> This patch adds support to 4 MI2S ports on LPASS.
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>> Reviewed-and-tested-by: Rohit kumar <rohitkr@codeaurora.org>
>> ---
>> sound/soc/qcom/qdsp6/q6afe.c | 224
>> +++++++++++++++++++++++++++++++++++++++++++
>> sound/soc/qcom/qdsp6/q6afe.h | 13 +++
>> 2 files changed, 237 insertions(+)
>>
>> diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c
>> index be55b3ab045f..ceb18aaa5af4 100644
>> --- a/sound/soc/qcom/qdsp6/q6afe.c
>> +++ b/sound/soc/qcom/qdsp6/q6afe.c
>> @@ -14,6 +14,10 @@
>> #include <linux/spinlock.h>
>> #include <linux/delay.h>
>> #include <linux/soc/qcom/apr.h>
>> +#include <sound/soc.h>
>> +#include <sound/soc-dai.h>
>> +#include <sound/pcm.h>
> <snip>
>
>> union afe_port_config {
>> struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch;
>> struct afe_param_id_slimbus_cfg slim_cfg;
>> + struct afe_param_id_i2s_cfg i2s_cfg;
>> } __packed;
>> struct q6afe_port {
>> @@ -210,6 +264,22 @@ static struct afe_port_map
>> port_maps[AFE_PORT_MAX] = {
>> SLIMBUS_4_RX, 1, 1},
>> [SLIMBUS_5_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX,
>> SLIMBUS_5_RX, 1, 1},
>> + [QUATERNARY_MI2S_RX] = { AFE_PORT_ID_QUATERNARY_MI2S_RX,
>> + QUATERNARY_MI2S_RX, 1, 1},
>> + [QUATERNARY_MI2S_TX] = { AFE_PORT_ID_QUATERNARY_MI2S_TX,
>> + QUATERNARY_MI2S_TX, 0, 1},
>> + [SECONDARY_MI2S_RX] = { AFE_PORT_ID_SECONDARY_MI2S_RX,
>> + SECONDARY_MI2S_RX, 1, 1},
>> + [SECONDARY_MI2S_TX] = { AFE_PORT_ID_SECONDARY_MI2S_TX,
>> + SECONDARY_MI2S_TX, 0, 1},
>> + [TERTIARY_MI2S_RX] = { AFE_PORT_ID_TERTIARY_MI2S_RX,
>> + TERTIARY_MI2S_RX, 1, 1},
>> + [TERTIARY_MI2S_TX] = { AFE_PORT_ID_TERTIARY_MI2S_TX,
>> + TERTIARY_MI2S_TX, 0, 1},
>> + [PRIMARY_MI2S_RX] = { AFE_PORT_ID_PRIMARY_MI2S_RX,
>> + PRIMARY_MI2S_RX, 1, 1},
>> + [PRIMARY_MI2S_TX] = { AFE_PORT_ID_PRIMARY_MI2S_TX,
>> + PRIMARY_MI2S_RX, 0, 1},
> Can these be added after SLIMBUS_6_RX?
> Also, for better arrangement, please add the port_maps from
> PRIMARY_MI2S_RX to QUATERNARY_MI2S_TX in the same sequence of definition
> of AFE ports.
> Otherwise LGTM.
Yep, I have reordered this now!
> Once fixed the above comment add-
> Acked-by: Banajit Goswami <bgoswami@codeaurora.org>
>
^ permalink raw reply
* [PATCH 3/4] coresight: allow to build as modules
From: Randy Dunlap @ 2018-05-09 6:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180508153756.09f6fa8066bc23a0d11ec670@arm.com>
On 05/08/2018 01:37 PM, Kim Phillips wrote:
> On Tue, 8 May 2018 12:31:08 -0700
> Randy Dunlap <rdunlap@infradead.org> wrote:
>
>> Hi,
>
> Hi,
>>> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h
>>> index 3ffc9feb2d64..8c49c7b82d84 100644
>>> --- a/drivers/hwtracing/coresight/coresight-etm-perf.h
>>> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.h
>>> @@ -54,7 +54,7 @@ struct etm_filters {
>>> };
>>>
>>>
>>> -#ifdef CONFIG_CORESIGHT
>>> +#if IS_ENABLED(CONFIG_CORESIGHT)
>>
>> Have you found (observed) that this change (above) is necessary (and others
>> like it below)? I thought that they would be equivalent.
>>
>> From include/linux/kconfig.h:
>> /*
>> * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm',
>> * 0 otherwise.
>> */
>> #define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option))
>>
>>
>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
>>> index f1d0e21d8cab..335bca44b42d 100644
>>> --- a/drivers/hwtracing/coresight/coresight-priv.h
>>> +++ b/drivers/hwtracing/coresight/coresight-priv.h
>>
>>> @@ -143,7 +149,7 @@ struct list_head *coresight_build_path(struct coresight_device *csdev,
>>> struct coresight_device *sink);
>>> void coresight_release_path(struct list_head *path);
>>>
>>> -#ifdef CONFIG_CORESIGHT_SOURCE_ETM3X
>>> +#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM3X)
>>
>> ditto.
>>
>>> extern int etm_readl_cp14(u32 off, unsigned int *val);
>>> extern int etm_writel_cp14(u32 off, u32 val);
>>> #else
>>
>>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>>> index d950dad5056a..5863eb1a7335 100644
>>> --- a/include/linux/coresight.h
>>> +++ b/include/linux/coresight.h
>>> @@ -243,7 +243,7 @@ struct coresight_ops {
>>> const struct coresight_ops_source *source_ops;
>>> };
>>>
>>> -#ifdef CONFIG_CORESIGHT
>>> +#if IS_ENABLED(CONFIG_CORESIGHT)
>>
>> ditto.
>
> If I revert all three IS_ENABLED back to plain #ifdefs, and rebuild with
> CONFIG_CORESIGHT*=m, I get:
>
[build errors deleted]
>
> Building CORESIGHT=y builds ok, so, building it as a module causes the
> latter stubs to be compiled:
>
> #ifdef CONFIG_CORESIGHT
> extern struct coresight_device *
> coresight_register(struct coresight_desc *desc);
> extern void coresight_unregister(struct coresight_device *csdev);
> extern int coresight_enable(struct coresight_device *csdev);
> extern void coresight_disable(struct coresight_device *csdev);
> extern int coresight_timeout(void __iomem *addr, u32 offset,
> int position, int value);
> #else
> static inline struct coresight_device *
> coresight_register(struct coresight_desc *desc) { return NULL; }
> static inline void coresight_unregister(struct coresight_device *csdev) {}
> static inline int
> coresight_enable(struct coresight_device *csdev) { return -ENOSYS; }
> static inline void coresight_disable(struct coresight_device *csdev) {}
> static inline int coresight_timeout(void __iomem *addr, u32 offset,
> int position, int value) { return 1; }
> #endif
>
> Adding kconfig.h to coresight.h's #include list doesn't help. So we
> need the IS_ENABLED for its __or(..., IS_MODULE()) case.
<linux/kconfig.h> is automatically #included by the top-level Makefile,
so adding it again would not help any. ;)
> That being said, I don't know of any outside kernel-build dependencies
> coresight.h might have.
OK, using
#if IS_ENABLED(CONFIG_CORESIGHT)
is fine. This is just the current/modern way of saying:
#if defined(CONFIG_CORESIGHT) || defined(CONFIG_CORESIGHT_MODULE)
There are several hundred instances of that latter form in the kernel tree.
thanks,
--
~Randy
^ permalink raw reply
* [RESEND PATCH] pinctrl: rockchip: Disable interrupt when changing it's capability
From: Doug Anderson @ 2018-05-09 5:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5AF25B2E.8080901@rock-chips.com>
Hi,
On Tue, May 8, 2018 at 7:21 PM, JeffyChen <jeffy.chen@rock-chips.com> wrote:
> Hi Doug,
>
> On 05/09/2018 03:46 AM, Doug Anderson wrote:
>>
>> One note is that in the case Brian points at (where we need to
>> simulate EDGE_BOTH by swapping edges) we purposely ignored the TRM and
>> we needed to do that to avoid losing interrupts. For details, see
>> commit 53b1bfc76df2 ("pinctrl: rockchip: Avoid losing interrupts when
>> supporting both edges"). We did this because:
>>
>> 1. We believed that the IP block in Rockchip SoCs has nearly the same
>> logic as "gpio-dwapb.c" and that's what "gpio-dwapb.c" did.
>>
>
> hmm, but i saw the gpio-dwapb.c actually toggle trigger after handle irq,
> which might avoid the race Brian mentioned:
> + generic_handle_irq(gpio_irq);
> + irq_status &= ~BIT(hwirq);
> +
> + if ((irq_get_trigger_type(gpio_irq) & IRQ_TYPE_SENSE_MASK)
> + == IRQ_TYPE_EDGE_BOTH)
> + dwapb_toggle_trigger(gpio, hwirq);
The code you point at in dwapb_toggle_trigger() specifically is an
example of toggling the polarity _without_ disabling the interrupt in
between. We took this as "working" code and as proof that it was OK
to change polarity without disabling the interrupt in-between.
> and i also saw ./qcom/pinctrl-msm.c do the
> toggle(msm_gpio_update_dual_edge_pos) at the end of msm_gpio_irq_set_type
> and msm_gpio_irq_ack, that seems can avoid the polarity races too.
>
>> 2. We were actually losing real interrupts and this was the only way
>> we could figure out how to fix it.
>>
>> When I tested that back in the day I was fairly convinced that we
>> weren't losing any interrupts in the EDGE_BOTH case after my fix, but
>> I certainly could have messed up.
>>
>>
>> For the EDGE_BOTH case it was important not to lose an interrupt
>> because, as you guys are talking about, we could end up configured the
>> wrong way. I think in your case where you're just picking one
>> polarity losing an interrupt shouldn't matter since it's undefined
>> exactly if an edge happens while you're in the middle of executing
>> rockchip_irq_set_type(). Is that right?
>
>
> right, so we now have 2 cases: rockchip_irq_demux/ rockchip_irq_set_type
>
> if i'm right about the spurious irq(only happen when set rising for a high
> gpio, or set falling for a low gpio), then:
>
> 1/ rockchip_irq_demux
> it's important to not losing irqs in this case, maybe we can
>
> a) ack irq
> b) update polarity for edge both irq
>
> we don't need to disable irq in b), since we would not hit the spurious irq
> cases here(always check gpio level to toggle it)
Unless you have some sort of proof that rockchip_irq_demux(), I would
take it as an example of something that works. I remember stress
testing the heck out of it. Do you have some evidence that it's not
working? I think Brian was simply speculating that there might be a
race here, but I don't think anyone has shown it have they? Looking
back at my notes, the thing I really made sure to stress was that we
never got into a situation where we were losing an edge (AKA we were
never configured to look for a falling edge when the line was already
low). I'm not sure I confirmed that we never got an extra interrupt.
I'm at home right now and I can't add prints and poke at things, but
as I understand it for edge interrupts the usual flow to make sure
interrupts aren't ever lost is:
1. See that the interrupt went off
2. Ack it (clear it)
3. Call the interrupt handler
...presumably in this case rockchip_irq_demux() is called after step
#2 (but I don't know if it's called before or after step #3). If the
line is toggling like crazy while the 3 steps are going on, it's OK if
the interrupt handler is called more than once. In general this could
be considered expected. That's why you Ack before handling--any extra
edges that come in any time after the interrupt handler starts (even
after the very first instruction) need to cause the interrupt handler
to get called again.
This is different than Brian's understanding since he seemed to think
the Ack was happening later. If you're in front of something where
you can add printouts, maybe you can tell us. I tried to look through
the code and it was too twisted for me to be sure.
> 2/ rockchip_irq_set_type
> it's important to not having spurious irqs
>
> so we can disable irq during changing polarity only in these case:
> ((rising && gpio is heigh) || (falling && gpio is low))
>
> i'm still confirming the spurious irq with IC guys.
Hmmm, thinking about all this more, I'm curious how callers expect
this to work. Certainly things are undefined if you have the
following situation:
Start: rising edge trigger, line is actually high
Request: change to falling edge trigger
Line falls during the request
In that case it's OK to throw the interrupt away because it can be
argued that the line could have fallen before the request actually
took place. ...but it seems like there could be situations where the
user wouldn't expect interrupts to be thrown away by a call to
irq_set_type(). In other words:
Start: rising edge trigger, line is actually high
Request: change to falling edge trigger
Line falls, rises, and falls during the request
...in that case you'd expect that some sort of interrupt would have
gone off and not be thrown away. No matter what instant in time the
request actually took place it should have caught an edge, right?
Said another way: As a client of irq_set_type() I'd expect it to not
throw away interrupts, but I'd expect that the change in type would be
atomic. That is: if the interrupt came in before the type change in
type applied then it should trigger with the old rules. If the
interrupt came in after the type change then it should trigger with
the new rules.
I would be tempted to confirm your testing and just clear the spurious
interrupts that you're aware of. AKA: if there's no interrupt pending
and you change the type to "IRQ_TYPE_EDGE_RISING" or
"IRQ_TYPE_EDGE_FALLING" then you should clear the interrupt. It's
still racy, but I guess it's the best you can do unless IC guys come
up with something better.
Anyway, it's past my bedtime. Hopefully some of the above made sense.
I'm sure you'll tell me if it didn't or if I said something
stupid/wrong. :-P
-Doug
^ permalink raw reply
* [PATCH 2/2] ARM: dts: BCM5301X: Add DT for Luxul XAP-1610
From: Rafał Miłecki @ 2018-05-09 5:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525450124-21665-2-git-send-email-dan.haab@luxul.com>
On 04.05.2018 18:08, Dan Haab wrote:
> It's an access point based on BCM47094 SoC with two BCM4366E wireless
> chipsets.
>
> Signed-off-by: Dan Haab <dan.haab@luxul.com>
Acked-by: Rafa? Mi?ecki <rafal@milecki.pl>
^ permalink raw reply
* [PATCH 1/2] ARM: dts: BCM5301X: Add DT for Luxul XWR-3150 V1
From: Rafał Miłecki @ 2018-05-09 5:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525450124-21665-1-git-send-email-dan.haab@luxul.com>
On 04.05.2018 18:08, Dan Haab wrote:
> Luxul XWR-3150 is a wireless router similar to the XWR-3100 except:
> 1) It has more RAM
> 2) Its NAND controller in running in BCH8 mode
> 3) LAN ports LEDs are hardware controlled
>
> Signed-off-by: Dan Haab <dan.haab@luxul.com>
Acked-by: Rafa? Mi?ecki <rafal@milecki.pl>
^ permalink raw reply
* [PATCH v6 2/6] ARM: imx6: register pm_power_off handler if "fsl,pmic-stby-poweroff" is set
From: Oleksij Rempel @ 2018-05-09 5:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180508124033.GL16141@n2100.armlinux.org.uk>
On Tue, May 08, 2018 at 01:40:33PM +0100, Russell King - ARM Linux wrote:
> On Mon, Mar 05, 2018 at 11:25:19AM +0100, Oleksij Rempel wrote:
> > One of the Freescale recommended sequences for power off with external
> > PMIC is the following:
> > ...
> > 3. SoC is programming PMIC for power off when standby is asserted.
> > 4. In CCM STOP mode, Standby is asserted, PMIC gates SoC supplies.
> >
> > See:
> > http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6DQRM.pdf
> > page 5083
> >
> > This patch implements step 4. of this sequence.
> >
> > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> > ---
> > arch/arm/mach-imx/pm-imx6.c | 25 +++++++++++++++++++++++++
> > 1 file changed, 25 insertions(+)
> >
> > diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
> > index ecdf071653d4..24689260a2a5 100644
> > --- a/arch/arm/mach-imx/pm-imx6.c
> > +++ b/arch/arm/mach-imx/pm-imx6.c
> > @@ -604,6 +604,28 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata
> > IMX6Q_GPR1_GINT);
> > }
> >
> > +static void imx6_pm_stby_poweroff(void)
> > +{
> > + imx6_set_lpm(STOP_POWER_OFF);
> > + cpu_suspend(0, imx6q_suspend_finish);
>
> Do you actually need to save the processor state etc here - the request
> is after all to power down the system and not to suspend. Would calling
> imx6q_suspend_finish() directly work (and hence simplify the code) ?
yes you right. This will work as well.
I'll send changed version after Rafaels feedback for kernel/reboot.c
part.
Russell, can I expect your Signed-off-by for changed patch?
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180509/206f1672/attachment.sig>
^ permalink raw reply
* centralize SWIOTLB config symbol and misc other cleanups V3
From: Christoph Hellwig @ 2018-05-09 5:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180502124617.GA22001@infradead.org>
On Wed, May 02, 2018 at 05:46:17AM -0700, Christoph Hellwig wrote:
> Any more comments? Especially from the x86, mips and powerpc arch
> maintainers? I'd like to merge this in a few days as various other
> patches depend on it.
I've pulled it in to make forward progress. Any additional comments
will have to be sent in the form of incremental patches.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox