{"id":1941008,"url":"http://patchwork.ozlabs.org/api/patches/1941008/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/0038be5713c19072fc83c37fb21a0083013e5f52.1716965617.git.ysato@users.sourceforge.jp/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<0038be5713c19072fc83c37fb21a0083013e5f52.1716965617.git.ysato@users.sourceforge.jp>","list_archive_url":null,"date":"2024-05-29T08:01:04","name":"[DO,NOT,MERGE,v8,18/36] irqchip: SH7751 external interrupt encoder with enable gate.","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"3ed0ff041907eec40a5585583581cb8fcfc06360","submitter":{"id":7114,"url":"http://patchwork.ozlabs.org/api/people/7114/?format=json","name":"Yoshinori Sato","email":"ysato@users.sourceforge.jp"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/0038be5713c19072fc83c37fb21a0083013e5f52.1716965617.git.ysato@users.sourceforge.jp/mbox/","series":[{"id":408652,"url":"http://patchwork.ozlabs.org/api/series/408652/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=408652","date":"2024-05-29T08:00:51","name":"Device Tree support for SH7751 based board","version":8,"mbox":"http://patchwork.ozlabs.org/series/408652/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/1941008/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/1941008/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <linux-pci+bounces-7972-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2604:1380:4601:e00::3; helo=am.mirrors.kernel.org;\n envelope-from=linux-pci+bounces-7972-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=153.127.30.23","smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=users.sourceforge.jp","smtp.subspace.kernel.org;\n spf=fail smtp.mailfrom=users.sourceforge.jp"],"Received":["from am.mirrors.kernel.org (am.mirrors.kernel.org\n [IPv6:2604:1380:4601:e00::3])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature ECDSA (secp384r1))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4Vq25t2h94z20Pr\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 May 2024 18:06:42 +1000 (AEST)","from smtp.subspace.kernel.org (wormhole.subspace.kernel.org\n [52.25.139.140])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby am.mirrors.kernel.org (Postfix) with ESMTPS id 6C49C1F2A5D2\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 May 2024 08:06:39 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 92AD817BB3C;\n\tWed, 29 May 2024 08:02:04 +0000 (UTC)","from sakura.ysato.name (ik1-413-38519.vs.sakura.ne.jp\n [153.127.30.23])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id A94D317B509;\n\tWed, 29 May 2024 08:02:02 +0000 (UTC)","from SIOS1075.ysato.name (al128006.dynamic.ppp.asahi-net.or.jp\n [111.234.128.6])\n\tby sakura.ysato.name (Postfix) with ESMTPSA id 8156F1C0F72;\n\tWed, 29 May 2024 17:02:00 +0900 (JST)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1716969724; cv=none;\n b=G3qUhgAi8bRBJi3Pl5q7vQADxvGo34gLAzD79P9vKvTPLba2rZLJoCZ0LQF4HJvTP7QMfXflPFBA/hH3WMICNOdt7eqzFttLisZ1MPnrxEzYwyOnQ0+TGsjPCF+DdMpGFhItcsOdG+UifUqKYmkFwZZ9D24G4zPcU5FmNjEKAms=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1716969724; c=relaxed/simple;\n\tbh=F3m11lmqUQqt+FK442voAGLAy+pxkLjU/TOQowsPS5I=;\n\th=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:\n\t MIME-Version;\n b=O/BB6Tr5yZYXDUau2EQtYJqWD/WJP/InPD5coXSUqTiQpjF7zBmFyDxNwK172ha8DoCP5nboo9jpMr/rlj/c/N0KAXh9fZG6ogvWeuAzdj21vd0RcUOGC0yFSJBKN/+09Bp0SKeISjQit7eJnJCJBmMw2wqTV7bkYTQFCgkt5LU=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=users.sourceforge.jp;\n spf=fail smtp.mailfrom=users.sourceforge.jp;\n arc=none smtp.client-ip=153.127.30.23","From":"Yoshinori Sato <ysato@users.sourceforge.jp>","To":"linux-sh@vger.kernel.org","Cc":"Yoshinori Sato <ysato@users.sourceforge.jp>,\n Damien Le Moal <dlemoal@kernel.org>, Niklas Cassel <cassel@kernel.org>,\n Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,\n Conor Dooley <conor+dt@kernel.org>,\n Geert Uytterhoeven <geert+renesas@glider.be>,\n Michael Turquette <mturquette@baylibre.com>, Stephen Boyd <sboyd@kernel.org>,\n David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>,\n Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,\n Maxime Ripard <mripard@kernel.org>, Thomas Zimmermann <tzimmermann@suse.de>,\n Thomas Gleixner <tglx@linutronix.de>, Bjorn Helgaas <bhelgaas@google.com>,\n Lorenzo Pieralisi <lpieralisi@kernel.org>, =?utf-8?q?Krzysztof_Wilczy=C5=84?=\n\t=?utf-8?q?ski?= <kw@linux.com>,\n Greg Kroah-Hartman <gregkh@linuxfoundation.org>,\n Jiri Slaby <jirislaby@kernel.org>, Magnus Damm <magnus.damm@gmail.com>,\n Daniel Lezcano <daniel.lezcano@linaro.org>, Rich Felker <dalias@libc.org>,\n John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>,\n Lee Jones <lee@kernel.org>, Helge Deller <deller@gmx.de>,\n Heiko Stuebner <heiko.stuebner@cherry.de>,\n Neil Armstrong <neil.armstrong@linaro.org>,\n Chris Morgan <macromorgan@hotmail.com>, Sebastian Reichel <sre@kernel.org>,\n Linus Walleij <linus.walleij@linaro.org>, Arnd Bergmann <arnd@arndb.de>,\n Masahiro Yamada <masahiroy@kernel.org>, Baoquan He <bhe@redhat.com>,\n Andrew Morton <akpm@linux-foundation.org>,\n Guenter Roeck <linux@roeck-us.net>, Kefeng Wang <wangkefeng.wang@huawei.com>,\n Stephen Rothwell <sfr@canb.auug.org.au>,\n Azeem Shaikh <azeemshaikh38@gmail.com>, Guo Ren <guoren@kernel.org>,\n Max Filippov <jcmvbkbc@gmail.com>, Jernej Skrabec <jernej.skrabec@gmail.com>,\n Herve Codina <herve.codina@bootlin.com>,\n Andy Shevchenko <andriy.shevchenko@linux.intel.com>,\n Anup Patel <apatel@ventanamicro.com>, Jacky Huang <ychuang3@nuvoton.com>,\n Hugo Villeneuve <hvilleneuve@dimonoff.com>, Jonathan Corbet <corbet@lwn.net>,\n Wolfram Sang <wsa+renesas@sang-engineering.com>, =?utf-8?q?Uwe_Kleine-K?=\n\t=?utf-8?q?=C3=B6nig?= <u.kleine-koenig@pengutronix.de>,\n Christophe JAILLET <christophe.jaillet@wanadoo.fr>,\n Sam Ravnborg <sam@ravnborg.org>,\n Javier Martinez Canillas <javierm@redhat.com>,\n Sergey Shtylyov <s.shtylyov@omp.ru>,\n Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>,\n linux-ide@vger.kernel.org, devicetree@vger.kernel.org,\n linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org,\n linux-clk@vger.kernel.org, dri-devel@lists.freedesktop.org,\n linux-pci@vger.kernel.org, linux-serial@vger.kernel.org,\n linux-fbdev@vger.kernel.org","Subject":"[DO NOT MERGE v8 18/36] irqchip: SH7751 external interrupt encoder\n with enable gate.","Date":"Wed, 29 May 2024 17:01:04 +0900","Message-Id":"\n <0038be5713c19072fc83c37fb21a0083013e5f52.1716965617.git.ysato@users.sourceforge.jp>","X-Mailer":"git-send-email 2.39.2","In-Reply-To":"<cover.1716965617.git.ysato@users.sourceforge.jp>","References":"<cover.1716965617.git.ysato@users.sourceforge.jp>","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit"},"content":"SH7751 have 15 level external interrupt.\nIt is typically connected to the CPU through a priority encoder\nthat can suppress requests.\nThis driver provides a way to control those hardware with irqchip.\n\nSigned-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>\n---\n drivers/irqchip/Kconfig                 |   7 +\n drivers/irqchip/Makefile                |   2 +\n drivers/irqchip/irq-renesas-sh7751irl.c | 221 ++++++++++++++++++++++++\n 3 files changed, 230 insertions(+)\n create mode 100644 drivers/irqchip/irq-renesas-sh7751irl.c","diff":"diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig\nindex f45a229963d4..50b2bdf157f1 100644\n--- a/drivers/irqchip/Kconfig\n+++ b/drivers/irqchip/Kconfig\n@@ -723,4 +723,11 @@ config RENESAS_SH7751_INTC\n \t  Support for the Renesas SH7751 On-chip interrupt controller.\n \t  And external interrupt encoder for some targets.\n \n+config RENESAS_SH7751IRL_INTC\n+\tbool \"Renesas SH7751 based target IRL encoder support.\"\n+\tdepends on RENESAS_SH7751_INTC\n+\thelp\n+\t  Support for External Interrupt encoder\n+\t  on the some Renesas SH7751 based target.\n+\n endmenu\ndiff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile\nindex 7bde45f05a1e..f99fa24927bc 100644\n--- a/drivers/irqchip/Makefile\n+++ b/drivers/irqchip/Makefile\n@@ -125,3 +125,5 @@ obj-$(CONFIG_APPLE_AIC)\t\t\t+= irq-apple-aic.o\n obj-$(CONFIG_MCHP_EIC)\t\t\t+= irq-mchp-eic.o\n obj-$(CONFIG_SUNPLUS_SP7021_INTC)\t+= irq-sp7021-intc.o\n obj-$(CONFIG_RENESAS_SH7751_INTC)\t+= irq-renesas-sh7751.o\n+obj-$(CONFIG_RENESAS_SH7751IRL_INTC)\t+= irq-renesas-sh7751irl.o\n+\ndiff --git a/drivers/irqchip/irq-renesas-sh7751irl.c b/drivers/irqchip/irq-renesas-sh7751irl.c\nnew file mode 100644\nindex 000000000000..5990f2cd9a3d\n--- /dev/null\n+++ b/drivers/irqchip/irq-renesas-sh7751irl.c\n@@ -0,0 +1,221 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/*\n+ * SH7751 based board external interrupt level encoder driver\n+ * (Renesas RTS7751R2D / IO DATA DEVICE LANDISK, USL-5P)\n+ *\n+ * Copyright (C) 2023 Yoshinori Sato\n+ */\n+\n+#include <linux/err.h>\n+#include <linux/init.h>\n+#include <linux/interrupt.h>\n+#include <linux/io.h>\n+#include <linux/irqdomain.h>\n+#include <linux/irq.h>\n+#include <linux/irqchip.h>\n+#include <linux/of.h>\n+#include <linux/of_irq.h>\n+#include <linux/of_address.h>\n+#include <linux/slab.h>\n+#include <linux/bitops.h>\n+\n+struct sh7751irl_intc_priv {\n+\tstruct irq_domain *irq_domain;\n+\tvoid __iomem\t  *base;\n+\tunsigned int\t  width;\n+\tbool\t\t  invert;\n+\tu32\t\t  enable_bit[NR_IRL];\n+};\n+\n+static inline unsigned long get_reg(void __iomem *addr, unsigned int w)\n+{\n+\tswitch (w) {\n+\tcase 8:\n+\t\treturn __raw_readb(addr);\n+\tcase 16:\n+\t\treturn __raw_readw(addr);\n+\tcase 32:\n+\t\treturn __raw_readl(addr);\n+\tdefault:\n+\t\t/* The size is checked when reading the properties. */\n+\t\tpr_err(\"%s: Invalid width %d\", __FILE__, w);\n+\t\treturn 0;\n+\t}\n+}\n+\n+static inline void set_reg(void __iomem *addr, unsigned int w, unsigned long val)\n+{\n+\tswitch (w) {\n+\tcase 8:\n+\t\t__raw_writeb(val, addr);\n+\t\tbreak;\n+\tcase 16:\n+\t\t__raw_writew(val, addr);\n+\t\tbreak;\n+\tcase 32:\n+\t\t__raw_writel(val, addr);\n+\t\tbreak;\n+\tdefault:\n+\t\tpr_err(\"%s: Invalid width %d\", __FILE__, w);\n+\t}\n+}\n+\n+static inline struct sh7751irl_intc_priv *irq_data_to_priv(struct irq_data *data)\n+{\n+\treturn data->domain->host_data;\n+}\n+\n+static void irl_endisable(struct irq_data *data, unsigned int enable)\n+{\n+\tstruct sh7751irl_intc_priv *priv;\n+\tunsigned long val;\n+\tunsigned int irl;\n+\n+\tpriv = irq_data_to_priv(data);\n+\tirl = irqd_to_hwirq(data) - IRL_BASE_IRQ;\n+\n+\tif (irl < NR_IRL && priv->enable_bit[irl] < priv->width) {\n+\t\tif (priv->invert)\n+\t\t\tenable = !enable;\n+\n+\t\tval = get_reg(priv->base, priv->width);\n+\t\tif (enable)\n+\t\t\tset_bit(priv->enable_bit[irl], &val);\n+\t\telse\n+\t\t\tclear_bit(priv->enable_bit[irl], &val);\n+\t\tset_reg(priv->base, priv->width, val);\n+\t} else {\n+\t\tpr_err(\"%s: Invalid register define in IRL %u\", __FILE__, irl);\n+\t}\n+}\n+\n+static void sh7751irl_intc_disable_irq(struct irq_data *data)\n+{\n+\tirl_endisable(data, 0);\n+}\n+\n+static void sh7751irl_intc_enable_irq(struct irq_data *data)\n+{\n+\tirl_endisable(data, 1);\n+}\n+\n+static struct irq_chip sh7751irl_intc_chip = {\n+\t.name\t\t= \"SH7751IRL-INTC\",\n+\t.irq_enable\t= sh7751irl_intc_enable_irq,\n+\t.irq_disable\t= sh7751irl_intc_disable_irq,\n+};\n+\n+static int sh7751irl_intc_map(struct irq_domain *h, unsigned int virq,\n+\t\t\t       irq_hw_number_t hw_irq_num)\n+{\n+\tirq_set_chip_and_handler(virq, &sh7751irl_intc_chip, handle_level_irq);\n+\tirq_get_irq_data(virq)->chip_data = h->host_data;\n+\tirq_modify_status(virq, IRQ_NOREQUEST, IRQ_NOPROBE);\n+\treturn 0;\n+}\n+\n+static int sh7751irl_intc_translate(struct irq_domain *domain,\n+\t\t\t       struct irq_fwspec *fwspec, unsigned long *hwirq,\n+\t\t\t       unsigned int *type)\n+{\n+\tif (fwspec->param[0] > NR_IRL)\n+\t\treturn -EINVAL;\n+\n+\tswitch (fwspec->param_count) {\n+\tcase 2:\n+\t\t*type = fwspec->param[1];\n+\t\tfallthrough;\n+\tcase 1:\n+\t\t*hwirq = fwspec->param[0] + IRL_BASE_IRQ;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\treturn 0;\n+}\n+\n+static const struct irq_domain_ops sh7751irl_intc_domain_ops = {\n+\t.map = sh7751irl_intc_map,\n+\t.translate = sh7751irl_intc_translate,\n+};\n+\n+static int __init load_irl_bit(struct device_node *node, struct sh7751irl_intc_priv *priv)\n+{\n+\tstruct property *enable_map;\n+\tconst __be32 *p;\n+\tu32 nr_bits, bit;\n+\tu32 irl;\n+\tint ret;\n+\n+\t/* Fill in unused */\n+\tmemset(priv->enable_bit, ~0, sizeof(priv->enable_bit));\n+\n+\tenable_map = of_find_property(node, \"renesas,enable-reg\", &nr_bits);\n+\tif (IS_ERR(enable_map))\n+\t\treturn PTR_ERR(enable_map);\n+\n+\tnr_bits /= sizeof(u32);\n+\tif (nr_bits > priv->width)\n+\t\treturn -EINVAL;\n+\n+\tret = nr_bits;\n+\tp = NULL;\n+\tfor (bit = nr_bits; bit > 0; bit--) {\n+\t\tp = of_prop_next_u32(enable_map, p, &irl);\n+\t\tif (p == NULL || irl > NR_IRL)\n+\t\t\treturn -EINVAL;\n+\t\tif (irl == NR_IRL)\n+\t\t\t/* IRL15 is unassined bit */\n+\t\t\tcontinue;\n+\t\tpriv->enable_bit[irl] = bit - 1;\n+\t}\n+\treturn ret;\n+}\n+\n+static int __init sh7751irl_init(struct device_node *node, struct device_node *parent)\n+{\n+\tstruct sh7751irl_intc_priv *priv;\n+\tstruct resource res;\n+\tstruct irq_domain *d;\n+\tvoid __iomem *base;\n+\tint ret = 0;\n+\n+\tif (of_address_to_resource(node, 0, &res))\n+\t\treturn -EINVAL;\n+\tif (resource_size(&res) > 4)\n+\t\treturn -EINVAL;\n+\n+\tbase = ioremap(res.start, resource_size(&res));\n+\tif (!base)\n+\t\treturn -EINVAL;\n+\n+\tpriv = kzalloc(sizeof(*priv), GFP_KERNEL);\n+\tif (!priv)\n+\t\treturn -ENOMEM;\n+\n+\tpriv->base = base;\n+\tpriv->width = 8 << resource_size(&res);\n+\n+\tret = load_irl_bit(node, priv);\n+\tif (ret < 0) {\n+\t\tpr_err(\"%pOFP: Invalid register define.\\n\", node);\n+\t\tgoto error;\n+\t}\n+\n+\td = irq_domain_add_tree(node, &sh7751irl_intc_domain_ops, priv);\n+\tif (d == NULL) {\n+\t\tpr_err(\"%pOFP: cannot initialize irq domain\\n\", node);\n+\t\tret = -ENOMEM;\n+\t\tgoto error;\n+\t}\n+\n+\tpriv->irq_domain = d;\n+\tirq_domain_update_bus_token(d, DOMAIN_BUS_WIRED);\n+\tpr_info(\"%pOFP: SH7751 External Interrupt encoder (input=%d)\", node, ret);\n+\treturn 0;\n+error:\n+\tkfree(priv);\n+\treturn ret;\n+}\n+\n+IRQCHIP_DECLARE(renesas_sh7751_irl, \"renesas,sh7751-irl-ext\", sh7751irl_init);\n","prefixes":["DO","NOT","MERGE","v8","18/36"]}