Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp146034ybi; Fri, 7 Jun 2019 05:45:23 -0700 (PDT) X-Google-Smtp-Source: APXvYqziWf6fbKmzjW6Rw2dQfmT9e2AUYEBiaBAPfkN6tAtolPKIeJtLtglxUhoK18BlMlv7eJ2Q X-Received: by 2002:a17:90a:9bca:: with SMTP id b10mr4519224pjw.90.1559911523771; Fri, 07 Jun 2019 05:45:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559911523; cv=none; d=google.com; s=arc-20160816; b=gN6GCo59Q/qjqfXhKFsJWOwgag55q91cY5RBHKwI0ksEDE8Q8/E13GZ8lmhgNZahNM zbtp4FPdzAD3j/tQ/DQeb92RglJ0bbtbRpgrwpkb1awC4z+Lvo59673M+P6zWkiAl6Q8 HR23QnTHoJzAKvswVJtQDuZpiyjgQqRXmd5lvH1zpxWjO8uHeUsghs4Wpsu9XneKhqem TpKX4btzCRUXA/rpqL5MgefdJlRrmpW+bX5Nf6a+KzuBa+e+TC5WlcWxQw0Hn5S9FVZw notDTrf9OGBlUBrKjFdac0td9ZS4Z/uF324VzegiLzmWY2d1cQESk2XO+PmsIyZhwzTS d18A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=GP7eW3auFGIGBulTsjQA4b0v7yIjFhXR0xu49A6SJeY=; b=fgwyOBUymOWQAKTrLmQpJnd6HgJ0yq/McTd6x1S7Qlcowv0+yCmK+o044g+Cat23lO Mt37IXw7jkNm9xosutWm9ZA9xLHRVv9HugraPl0USWWhEJpk5gkHS5NFMobejooUiTdR ZpcxM4m9p9+xsOlnbmIlD4r9nAawlecVHYlBUshaCn2eIyQEWPWURp7CwyOgGcvg8ea/ 7/lnAZr7zSGXz5rlfz5o4egR0+W0Njus3+AooPjPC4eWCtE2+6EYEQzq/2gyHKZzHofE SnDegz73AvlsodcVQhFrnKb6FaiF66ePLm6of8M1czzPbw5bcOa8EzcDnnwbZjeJboW3 Gy3w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d12si1653131pla.121.2019.06.07.05.45.06; Fri, 07 Jun 2019 05:45:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728338AbfFGMmy (ORCPT + 99 others); Fri, 7 Jun 2019 08:42:54 -0400 Received: from olimex.com ([184.105.72.32]:37551 "EHLO olimex.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727386AbfFGMmw (ORCPT ); Fri, 7 Jun 2019 08:42:52 -0400 Received: from localhost.localdomain ([94.155.250.134]) by olimex.com with ESMTPSA (ECDHE-RSA-AES128-GCM-SHA256:TLSv1.2:Kx=ECDH:Au=RSA:Enc=AESGCM(128):Mac=AEAD) (SMTP-AUTH username stefan@olimex.com, mechanism PLAIN) for ; Fri, 7 Jun 2019 05:42:50 -0700 From: Stefan Mavrodiev To: Heiko Stuebner , Lee Jones , linux-kernel@vger.kernel.org Cc: Stefan Mavrodiev Subject: [PATCH v3 1/2] mfd: rk808: Check pm_power_off pointer Date: Fri, 7 Jun 2019 15:42:25 +0300 Message-Id: <20190607124226.17694-2-stefan@olimex.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190607124226.17694-1-stefan@olimex.com> References: <20190607124226.17694-1-stefan@olimex.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The function pointer pm_power_off may point to function from other module (PSCI for example). If rk808 is removed, pm_power_off is overwritten to NULL and the system cannot be powered off. This patch checks if pm_power_off points to a module function. Signed-off-by: Stefan Mavrodiev --- Changes is v3: - Add explanation comments Changes in v2: - Initial release actually drivers/mfd/rk808.c | 17 +++++++++++------ include/linux/mfd/rk808.h | 1 + 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c index 94377782d208..46d26e141cc4 100644 --- a/drivers/mfd/rk808.c +++ b/drivers/mfd/rk808.c @@ -438,7 +438,6 @@ static int rk808_probe(struct i2c_client *client, struct rk808 *rk808; const struct rk808_reg_data *pre_init_reg; const struct mfd_cell *cells; - void (*pm_pwroff_fn)(void); int nr_pre_init_regs; int nr_cells; int pm_off = 0, msb, lsb; @@ -475,7 +474,7 @@ static int rk808_probe(struct i2c_client *client, nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg); cells = rk805s; nr_cells = ARRAY_SIZE(rk805s); - pm_pwroff_fn = rk805_device_shutdown; + rk808->pm_pwroff_fn = rk805_device_shutdown; break; case RK808_ID: rk808->regmap_cfg = &rk808_regmap_config; @@ -484,7 +483,7 @@ static int rk808_probe(struct i2c_client *client, nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg); cells = rk808s; nr_cells = ARRAY_SIZE(rk808s); - pm_pwroff_fn = rk808_device_shutdown; + rk808->pm_pwroff_fn = rk808_device_shutdown; break; case RK818_ID: rk808->regmap_cfg = &rk818_regmap_config; @@ -493,7 +492,7 @@ static int rk808_probe(struct i2c_client *client, nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg); cells = rk818s; nr_cells = ARRAY_SIZE(rk818s); - pm_pwroff_fn = rk818_device_shutdown; + rk808->pm_pwroff_fn = rk818_device_shutdown; break; default: dev_err(&client->dev, "Unsupported RK8XX ID %lu\n", @@ -548,7 +547,7 @@ static int rk808_probe(struct i2c_client *client, "rockchip,system-power-controller"); if (pm_off && !pm_power_off) { rk808_i2c_client = client; - pm_power_off = pm_pwroff_fn; + pm_power_off = rk808->pm_pwroff_fn; } return 0; @@ -563,7 +562,13 @@ static int rk808_remove(struct i2c_client *client) struct rk808 *rk808 = i2c_get_clientdata(client); regmap_del_irq_chip(client->irq, rk808->irq_data); - pm_power_off = NULL; + + /** + * pm_power_off may points to a function from another module. + * Check if the pointer is set by us and only then overwrite it. + */ + if (rk808->pm_pwroff_fn && pm_power_off == rk808->pm_pwroff_fn) + pm_power_off = NULL; return 0; } diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h index d3156594674c..8b5d68a7bb9c 100644 --- a/include/linux/mfd/rk808.h +++ b/include/linux/mfd/rk808.h @@ -453,5 +453,6 @@ struct rk808 { long variant; const struct regmap_config *regmap_cfg; const struct regmap_irq_chip *regmap_irq_chip; + void (*pm_pwroff_fn)(void); }; #endif /* __LINUX_REGULATOR_RK808_H */ -- 2.17.1