mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
clk: starfive: Avoid casting iomem pointers
Let's use a wrapper struct for the auxiliary_device made in
jh7110_reset_controller_register() so that we can stop casting iomem
pointers. The casts trip up tools like sparse, and make for some awkward
casts that are largely unnecessary. While we're here, change the
allocation from devm and actually free the auxiliary_device memory in
the release function. This avoids any use after free problems where the
parent device driver is unbound from the device but the
auxiliuary_device is still in use accessing devm freed memory.
Cc: Tommaso Merciai <tomm.merciai@gmail.com>
Cc: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Cc: Hal Feng <hal.feng@starfivetech.com>
Cc: Conor Dooley <conor.dooley@microchip.com>
Cc: Xingyu Wu <xingyu.wu@starfivetech.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Fixes: edab7204af
("clk: starfive: Add StarFive JH7110 system clock driver")
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20230413205528.4044216-1-sboyd@kernel.org
This commit is contained in:
parent
601e5d464d
commit
d1aae06630
@ -11,6 +11,9 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include <soc/starfive/reset-starfive-jh71x0.h>
|
||||||
|
|
||||||
#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
#include <dt-bindings/clock/starfive,jh7110-crg.h>
|
||||||
|
|
||||||
@ -335,26 +338,32 @@ static void jh7110_reset_unregister_adev(void *_adev)
|
|||||||
struct auxiliary_device *adev = _adev;
|
struct auxiliary_device *adev = _adev;
|
||||||
|
|
||||||
auxiliary_device_delete(adev);
|
auxiliary_device_delete(adev);
|
||||||
|
auxiliary_device_uninit(adev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jh7110_reset_adev_release(struct device *dev)
|
static void jh7110_reset_adev_release(struct device *dev)
|
||||||
{
|
{
|
||||||
struct auxiliary_device *adev = to_auxiliary_dev(dev);
|
struct auxiliary_device *adev = to_auxiliary_dev(dev);
|
||||||
|
struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
|
||||||
|
|
||||||
auxiliary_device_uninit(adev);
|
kfree(rdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
|
int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
|
||||||
const char *adev_name,
|
const char *adev_name,
|
||||||
u32 adev_id)
|
u32 adev_id)
|
||||||
{
|
{
|
||||||
|
struct jh71x0_reset_adev *rdev;
|
||||||
struct auxiliary_device *adev;
|
struct auxiliary_device *adev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
adev = devm_kzalloc(priv->dev, sizeof(*adev), GFP_KERNEL);
|
rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
|
||||||
if (!adev)
|
if (!rdev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rdev->base = priv->base;
|
||||||
|
|
||||||
|
adev = &rdev->adev;
|
||||||
adev->name = adev_name;
|
adev->name = adev_name;
|
||||||
adev->dev.parent = priv->dev;
|
adev->dev.parent = priv->dev;
|
||||||
adev->dev.release = jh7110_reset_adev_release;
|
adev->dev.release = jh7110_reset_adev_release;
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include <linux/auxiliary_bus.h>
|
#include <linux/auxiliary_bus.h>
|
||||||
|
|
||||||
|
#include <soc/starfive/reset-starfive-jh71x0.h>
|
||||||
|
|
||||||
#include "reset-starfive-jh71x0.h"
|
#include "reset-starfive-jh71x0.h"
|
||||||
|
|
||||||
#include <dt-bindings/reset/starfive,jh7110-crg.h>
|
#include <dt-bindings/reset/starfive,jh7110-crg.h>
|
||||||
@ -33,14 +35,15 @@ static int jh7110_reset_probe(struct auxiliary_device *adev,
|
|||||||
const struct auxiliary_device_id *id)
|
const struct auxiliary_device_id *id)
|
||||||
{
|
{
|
||||||
struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
|
struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
|
||||||
void __iomem **base = (void __iomem **)dev_get_drvdata(adev->dev.parent);
|
struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
|
||||||
|
void __iomem *base = rdev->base;
|
||||||
|
|
||||||
if (!info || !base)
|
if (!info || !base)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
|
return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
|
||||||
*base + info->assert_offset,
|
base + info->assert_offset,
|
||||||
*base + info->status_offset,
|
base + info->status_offset,
|
||||||
NULL,
|
NULL,
|
||||||
info->nr_resets,
|
info->nr_resets,
|
||||||
NULL);
|
NULL);
|
||||||
|
17
include/soc/starfive/reset-starfive-jh71x0.h
Normal file
17
include/soc/starfive/reset-starfive-jh71x0.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#ifndef __SOC_STARFIVE_RESET_JH71X0_H
|
||||||
|
#define __SOC_STARFIVE_RESET_JH71X0_H
|
||||||
|
|
||||||
|
#include <linux/auxiliary_bus.h>
|
||||||
|
#include <linux/compiler_types.h>
|
||||||
|
#include <linux/container_of.h>
|
||||||
|
|
||||||
|
struct jh71x0_reset_adev {
|
||||||
|
void __iomem *base;
|
||||||
|
struct auxiliary_device adev;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define to_jh71x0_reset_adev(_adev) \
|
||||||
|
container_of((_adev), struct jh71x0_reset_adev, adev)
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user