Received: by 2002:a05:7208:9594:b0:7e:5202:c8b4 with SMTP id gs20csp2030947rbb; Tue, 27 Feb 2024 08:33:09 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCW5d+yhHdJJ46R7pygC7aL6Lel3EV0tgcEtaCjF+uoi5wZTgXzqPLf2C2T8D6UGkAHwuvuVUnIjt0es50c7zkcgv/2dBNyUYJ+QTitq0g== X-Google-Smtp-Source: AGHT+IG1QgEbZsU7H9Oegzj+yL3HgR4NRmfi8Zr8Cw/3C3AOj8/n3gAcPBqVGIL58tZAJUrDATtj X-Received: by 2002:aa7:d898:0:b0:566:44b4:ea58 with SMTP id u24-20020aa7d898000000b0056644b4ea58mr1272836edq.38.1709051589684; Tue, 27 Feb 2024 08:33:09 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709051589; cv=pass; d=google.com; s=arc-20160816; b=zxB4s5xcwWXYHkrGIJC4biUPAp6VoZ7rD+2nq+R/Kw8YwgmBAfuCBj0eulc7rDv3FO nrvtHqgdL9kIuqU3E6qDWfIGmRb8qUDYZpq+7CryaLGIlccZyYSTYCrfrDDV1RjURp20 +DdiEHcIfXDkpD9Ljs2dL1YSJebqVwWaMaKrgeCZRrGKLXCvrOWTR0zSDybLEqVqXtJ4 I+OCPaiHYP22sG3TQyTBYZixPYCoXyk2b/DnB5b2xDTYExouuCwVh21qO0Pe0AJsyYUX 2YygJtGbLLFYqfGNTWMjaO/uEsPs+0XqU5p4sZ16FwKPe14K11cH2s5aLHI2XYX/dUg6 ZAjw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:list-unsubscribe:list-subscribe:list-id:precedence :message-id:date:references:in-reply-to:subject:cc:to:dkim-signature :dkim-signature:from; bh=SyV9bHeQYh2STSu1Aki+bC1PiR0RG4rZPyWUkh6MdoI=; fh=BO+O71VMo4PDC3yTiicxKD0+lEIeU+PyW5c34dgUr7Q=; b=ZOCeKyJf4hsV/iUUtPj/Q4Mu8Ddx7NiefpbQf1to7QaGvIZIFQMcOXgbOWSKNNVLIO QUfbV76obel9HLOn2IIYykLUq9uwEWBehJmfdAjBsEuiEx4bt2uSVuYZ93M7MM0xcK4D Uh1/rCo1tKijSQLzL+MzMHgEuAIXqhxSC58M2+CIbXrk95YYnXDSLnhnUAoYyO1hgAvy q+b9khevnrkGVw3ZB9mp9ro6R9rkvHWpTI+mOBL4iqRbruDzkFyHxI2CttM8NxwVvicm qhh6iRc2NlsdRcBEkg+yZUrTi28jjvCXb99OPmTSGZ6ew3e2Rr5qUz4ZiM5vxY1/0ZQS 0iBg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=R0+sMRFv; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; arc=pass (i=1 spf=pass spfdomain=linutronix.de dkim=pass dkdomain=linutronix.de dmarc=pass fromdomain=linutronix.de); spf=pass (google.com: domain of linux-kernel+bounces-83610-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-83610-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id y5-20020a50eb05000000b005664e01c5b9si247591edp.545.2024.02.27.08.33.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Feb 2024 08:33:09 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-83610-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=R0+sMRFv; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; arc=pass (i=1 spf=pass spfdomain=linutronix.de dkim=pass dkdomain=linutronix.de dmarc=pass fromdomain=linutronix.de); spf=pass (google.com: domain of linux-kernel+bounces-83610-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-83610-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 722301F22AEF for ; Tue, 27 Feb 2024 16:33:09 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5EF8E1F606; Tue, 27 Feb 2024 16:32:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="R0+sMRFv"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="mfiDY1/j" Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA1901C697; Tue, 27 Feb 2024 16:32:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709051578; cv=none; b=FYmXWaZ0T1gk7WG40K1CY5r0vfFvPuylWriMLZMO2f09Esd6rkjjqxNMczj4BagKgGgDsG+iJ1x2LjabZPZjMK/FYeIWB2SSCoVuONZXgla8za9va+x68HY2AR09MwY2xKSCfYdMWt17J1IqhOkITWAe1ceDcY49jK/vnlwu5j0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709051578; c=relaxed/simple; bh=t9pqBmZVkQ/Fpn1eD9/FTS+0fHOWuP1ehf9RwlvwGww=; h=From:To:Cc:Subject:In-Reply-To:References:Date:Message-ID: MIME-Version:Content-Type; b=lUwaLnQvEjKIimabc0F6j/NhuSsoCnobCWPbNppn7DQCw3ufTLsbR1j7aBsvfGxaTQ1VKm+/P7MafpJg3tGJV9IvM57rfPQAWnR7toQCUKxvCp4zf84+MYKCsnUSWREtfz/J/YxXH+AC61uWnMh6yi4pGyEPL02BtMGkWT5bNIE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=R0+sMRFv; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=mfiDY1/j; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de From: Thomas Gleixner DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1709051574; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=SyV9bHeQYh2STSu1Aki+bC1PiR0RG4rZPyWUkh6MdoI=; b=R0+sMRFv9b8X+E5PlHqAnffQ9ul2R0l+89oJsQQqPEMzobmGax2CGW1kgeoxp2g7FE7y/H ZduHQ6oyjWkm9ZA5CLqotQqDCEtKhwhNagXbhtZj6x2P+eXwHgq8bn9YKdtPqmPMLZ9XkY 0M9kSqf3ORH7ZF9SDePLRmHMbqIQkX3kvhftVrbUGqMyDdK+NZuwrz7YR5i9fjoBUyHlEZ SK+iNEKoWW3HFdwTwutyndjzwqx2Aso9GloWF+coyojZ7RwUTRw16z46SpvLt8Du7dXC26 ttqFrpCCC/bMioXhJFtXB4Q09O1kXf9MzyxWlYi+Q24GgLZuajw5i7BshrGUfw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1709051574; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=SyV9bHeQYh2STSu1Aki+bC1PiR0RG4rZPyWUkh6MdoI=; b=mfiDY1/jYFYVkT3N2Y3yq9fwkvbnzRzZ3jJHlKwl01nm/DAsIpCmKZZwXdjDRmVLCuGQl6 9QNGSBRBpVnBP7Cg== To: Xingyu Wu , Daniel Lezcano , Emil Renner Berthing , Christophe JAILLET Cc: linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, Rob Herring , Krzysztof Kozlowski , Paul Walmsley , Palmer Dabbelt , Albert Ou , Philipp Zabel , Walker Chen , Xingyu Wu , linux-kernel@vger.kernel.org, Conor Dooley Subject: Re: [PATCH v8 2/3] clocksource: Add JH7110 timer driver In-Reply-To: <20231219145402.7879-3-xingyu.wu@starfivetech.com> References: <20231219145402.7879-1-xingyu.wu@starfivetech.com> <20231219145402.7879-3-xingyu.wu@starfivetech.com> Date: Tue, 27 Feb 2024 17:32:54 +0100 Message-ID: <877cipamvd.ffs@tglx> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain On Tue, Dec 19 2023 at 22:54, Xingyu Wu wrote: > + > +struct jh7110_clkevt { > + struct clk *clk; > + struct reset_control *rst; > + void __iomem *base; > + u32 reload_val; > + int irq; > + char name[sizeof("jh7110-timer.chX")]; > +}; > + > +struct jh7110_timer_priv { > + struct reset_control *prst; > + struct device *dev; > + struct jh7110_clkevt clkevt[JH7110_TIMER_CH_MAX]; > +}; Please format your data structures according to documentation: https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#struct-declarations-and-initializers > +/* IRQ handler for the timer */ > +static irqreturn_t jh7110_timer_interrupt(int irq, void *data) > +{ > + struct clock_event_device *evt = data; > + struct jh7110_clkevt *clkevt = &jh7110_timer_info.clkevt[0]; > + u8 cpu_id = smp_processor_id(); > + u32 reg = readl(clkevt->base + JH7110_TIMER_INT_STATUS); https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations > + /* Check interrupt status and channel(cpu) ID */ > + if (!(reg & BIT(cpu_id))) > + return IRQ_NONE; > + > + clkevt = &jh7110_timer_info.clkevt[cpu_id]; > + writel(JH7110_TIMER_INT_CLR_ENA, (clkevt->base + JH7110_TIMER_INT_CLR)); > + > + if (evt->event_handler) > + evt->event_handler(evt); > + > + return IRQ_HANDLED; > +} > + > +static int jh7110_timer_set_periodic(struct clock_event_device *evt) > +{ > + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT; > + > + writel(JH7110_TIMER_MODE_CONTIN, clkevt->base + JH7110_TIMER_CTL); > + return 0; > +} > + > +static int jh7110_timer_set_oneshot(struct clock_event_device *evt) > +{ > + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT; > + > + writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL); > + return 0; > +} > + > +static int jh7110_timer_set_next_event(unsigned long next, > + struct clock_event_device *evt) > +{ > + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT; > + > + writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL); > + writel(next, clkevt->base + JH7110_TIMER_LOAD); > + > + return jh7110_timer_start(clkevt); > +} > + > +static DEFINE_PER_CPU(struct clock_event_device, jh7110_clock_event) = { > + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, > + .rating = JH7110_CLOCKEVENT_RATING, > + .set_state_shutdown = jh7110_timer_shutdown, > + .set_state_periodic = jh7110_timer_set_periodic, > + .set_state_oneshot = jh7110_timer_set_oneshot, > + .set_state_oneshot_stopped = jh7110_timer_shutdown, > + .tick_resume = jh7110_timer_tick_resume, > + .set_next_event = jh7110_timer_set_next_event, > + .suspend = jh7110_timer_suspend, > + .resume = jh7110_timer_resume, > +}; See formatting rules. > +static int jh7110_timer_starting_cpu(unsigned int cpu) > +{ > + struct clock_event_device *evt = per_cpu_ptr(&jh7110_clock_event, cpu); > + struct jh7110_timer_priv *priv = &jh7110_timer_info; > + int ret; > + u32 rate; > + > + if (cpu >= JH7110_TIMER_CH_MAX) > + return -ENOMEM; > + > + ret = clk_prepare_enable(priv->clkevt[cpu].clk); > + if (ret) > + return ret; > + > + ret = reset_control_deassert(priv->clkevt[cpu].rst); > + if (ret) > + return ret; > + > + rate = clk_get_rate(priv->clkevt[cpu].clk); > + evt->cpumask = cpumask_of(cpu); > + evt->irq = priv->clkevt[cpu].irq; > + evt->name = priv->clkevt[cpu].name; > + clockevents_config_and_register(evt, rate, JH7110_TIMER_MIN_TICKS, > + JH7110_TIMER_MAX_TICKS); > + > + ret = devm_request_irq(priv->dev, evt->irq, jh7110_timer_interrupt, > + IRQF_TIMER | IRQF_IRQPOLL, > + evt->name, evt); How is this all supposed to work from a CPU hotplug state callback which runs in the early bringup phase with interrupts disabled? clk_prepare() which is invoked from clk_prepare_enable() can sleep and devm_request_irq() can sleep too. Did you ever test this with the required debug config options enabled? https://www.kernel.org/doc/html/latest/process/submit-checklist.html Obviously not. > + if (ret) > + return ret; > + > + ret = irq_set_affinity(evt->irq, cpumask_of(cpu)); > + if (ret) > + return ret; > + /* Use one-shot mode */ > + writel(JH7110_TIMER_MODE_SINGLE, (priv->clkevt[cpu].base + JH7110_TIMER_CTL)); > + > + return jh7110_timer_start(&priv->clkevt[cpu]); > +} > + > +static void jh7110_timer_release(void *data) > +{ > + struct jh7110_timer_priv *priv = data; > + int i; > + > + for (i = 0; i < JH7110_TIMER_CH_MAX; i++) { > + /* Disable each channel of timer */ > + if (priv->clkevt[i].base) > + writel(JH7110_TIMER_DIS, priv->clkevt[i].base + JH7110_TIMER_ENABLE); > + > + /* Avoid no initialization in the loop of the probe */ > + if (!IS_ERR_OR_NULL(priv->clkevt[i].rst)) > + reset_control_assert(priv->clkevt[i].rst); > + > + if (!IS_ERR_OR_NULL(priv->clkevt[i].clk)) > + clk_disable_unprepare(priv->clkevt[i].clk); Same problem. And of course this does not undo the other steps of jh7110_timer_starting_cpu() so if you offline a CPU and then online it again the callback will fail because the clockevent is already registered and the interrupt requested. Clearly untested too. Thanks, tglx