Skip to content

Commit a2be37e

Browse files
committed
firmware: exynos-acpm: Drop fake 'const' on handle pointer
All the functions operating on the 'handle' pointer are claiming it is a pointer to const thus they should not modify the handle. In fact that's a false statement, because first thing these functions do is drop the cast to const with container_of: struct acpm_info *acpm = handle_to_acpm_info(handle); And with such cast the handle is easily writable with simple: acpm->handle.ops.pmic_ops.read_reg = NULL; The code is not correct logically, either, because functions like acpm_get_by_node() and acpm_handle_put() are meant to modify the handle reference counting, thus they must modify the handle. Modification here happens anyway, even if the reference counting is stored in the container which the handle is part of. The code does not have actual visible bug, but incorrect 'const' annotations could lead to incorrect compiler decisions. Fixes: a88927b ("firmware: add Exynos ACPM protocol driver") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Link: https://patch.msgid.link/20260224104203.42950-2-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
1 parent f2e8307 commit a2be37e

9 files changed

Lines changed: 48 additions & 52 deletions

File tree

drivers/clk/samsung/clk-acpm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct acpm_clk {
2020
u32 id;
2121
struct clk_hw hw;
2222
unsigned int mbox_chan_id;
23-
const struct acpm_handle *handle;
23+
struct acpm_handle *handle;
2424
};
2525

2626
struct acpm_clk_variant {
@@ -113,7 +113,7 @@ static int acpm_clk_register(struct device *dev, struct acpm_clk *aclk,
113113

114114
static int acpm_clk_probe(struct platform_device *pdev)
115115
{
116-
const struct acpm_handle *acpm_handle;
116+
struct acpm_handle *acpm_handle;
117117
struct clk_hw_onecell_data *clk_data;
118118
struct clk_hw **hws;
119119
struct device *dev = &pdev->dev;

drivers/firmware/samsung/exynos-acpm-dvfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static void acpm_dvfs_init_set_rate_cmd(u32 cmd[4], unsigned int clk_id,
4343
cmd[3] = ktime_to_ms(ktime_get());
4444
}
4545

46-
int acpm_dvfs_set_rate(const struct acpm_handle *handle,
46+
int acpm_dvfs_set_rate(struct acpm_handle *handle,
4747
unsigned int acpm_chan_id, unsigned int clk_id,
4848
unsigned long rate)
4949
{
@@ -63,7 +63,7 @@ static void acpm_dvfs_init_get_rate_cmd(u32 cmd[4], unsigned int clk_id)
6363
cmd[3] = ktime_to_ms(ktime_get());
6464
}
6565

66-
unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
66+
unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle,
6767
unsigned int acpm_chan_id, unsigned int clk_id)
6868
{
6969
struct acpm_xfer xfer;

drivers/firmware/samsung/exynos-acpm-dvfs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111

1212
struct acpm_handle;
1313

14-
int acpm_dvfs_set_rate(const struct acpm_handle *handle,
14+
int acpm_dvfs_set_rate(struct acpm_handle *handle,
1515
unsigned int acpm_chan_id, unsigned int id,
1616
unsigned long rate);
17-
unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
17+
unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle,
1818
unsigned int acpm_chan_id,
1919
unsigned int clk_id);
2020

drivers/firmware/samsung/exynos-acpm-pmic.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static void acpm_pmic_init_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan)
7777
cmd[3] = ktime_to_ms(ktime_get());
7878
}
7979

80-
int acpm_pmic_read_reg(const struct acpm_handle *handle,
80+
int acpm_pmic_read_reg(struct acpm_handle *handle,
8181
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
8282
u8 *buf)
8383
{
@@ -107,7 +107,7 @@ static void acpm_pmic_init_bulk_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
107107
FIELD_PREP(ACPM_PMIC_VALUE, count);
108108
}
109109

110-
int acpm_pmic_bulk_read(const struct acpm_handle *handle,
110+
int acpm_pmic_bulk_read(struct acpm_handle *handle,
111111
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
112112
u8 count, u8 *buf)
113113
{
@@ -150,7 +150,7 @@ static void acpm_pmic_init_write_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
150150
cmd[3] = ktime_to_ms(ktime_get());
151151
}
152152

153-
int acpm_pmic_write_reg(const struct acpm_handle *handle,
153+
int acpm_pmic_write_reg(struct acpm_handle *handle,
154154
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
155155
u8 value)
156156
{
@@ -187,7 +187,7 @@ static void acpm_pmic_init_bulk_write_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
187187
}
188188
}
189189

190-
int acpm_pmic_bulk_write(const struct acpm_handle *handle,
190+
int acpm_pmic_bulk_write(struct acpm_handle *handle,
191191
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
192192
u8 count, const u8 *buf)
193193
{
@@ -220,7 +220,7 @@ static void acpm_pmic_init_update_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
220220
cmd[3] = ktime_to_ms(ktime_get());
221221
}
222222

223-
int acpm_pmic_update_reg(const struct acpm_handle *handle,
223+
int acpm_pmic_update_reg(struct acpm_handle *handle,
224224
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
225225
u8 value, u8 mask)
226226
{

drivers/firmware/samsung/exynos-acpm-pmic.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@
1111

1212
struct acpm_handle;
1313

14-
int acpm_pmic_read_reg(const struct acpm_handle *handle,
14+
int acpm_pmic_read_reg(struct acpm_handle *handle,
1515
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
1616
u8 *buf);
17-
int acpm_pmic_bulk_read(const struct acpm_handle *handle,
17+
int acpm_pmic_bulk_read(struct acpm_handle *handle,
1818
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
1919
u8 count, u8 *buf);
20-
int acpm_pmic_write_reg(const struct acpm_handle *handle,
20+
int acpm_pmic_write_reg(struct acpm_handle *handle,
2121
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
2222
u8 value);
23-
int acpm_pmic_bulk_write(const struct acpm_handle *handle,
23+
int acpm_pmic_bulk_write(struct acpm_handle *handle,
2424
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
2525
u8 count, const u8 *buf);
26-
int acpm_pmic_update_reg(const struct acpm_handle *handle,
26+
int acpm_pmic_update_reg(struct acpm_handle *handle,
2727
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
2828
u8 value, u8 mask);
2929
#endif /* __EXYNOS_ACPM_PMIC_H__ */

drivers/firmware/samsung/exynos-acpm.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ static int acpm_wait_for_message_response(struct acpm_chan *achan,
410410
*
411411
* Return: 0 on success, -errno otherwise.
412412
*/
413-
int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer)
413+
int acpm_do_xfer(struct acpm_handle *handle, const struct acpm_xfer *xfer)
414414
{
415415
struct acpm_info *acpm = handle_to_acpm_info(handle);
416416
struct exynos_mbox_msg msg;
@@ -674,7 +674,7 @@ static int acpm_probe(struct platform_device *pdev)
674674
* acpm_handle_put() - release the handle acquired by acpm_get_by_phandle.
675675
* @handle: Handle acquired by acpm_get_by_phandle.
676676
*/
677-
static void acpm_handle_put(const struct acpm_handle *handle)
677+
static void acpm_handle_put(struct acpm_handle *handle)
678678
{
679679
struct acpm_info *acpm = handle_to_acpm_info(handle);
680680
struct device *dev = acpm->dev;
@@ -700,9 +700,11 @@ static void devm_acpm_release(struct device *dev, void *res)
700700
* @np: ACPM device tree node.
701701
*
702702
* Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
703+
*
704+
* Note: handle CANNOT be pointer to const
703705
*/
704-
static const struct acpm_handle *acpm_get_by_node(struct device *dev,
705-
struct device_node *np)
706+
static struct acpm_handle *acpm_get_by_node(struct device *dev,
707+
struct device_node *np)
706708
{
707709
struct platform_device *pdev;
708710
struct device_link *link;
@@ -743,10 +745,10 @@ static const struct acpm_handle *acpm_get_by_node(struct device *dev,
743745
*
744746
* Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
745747
*/
746-
const struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
747-
struct device_node *np)
748+
struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
749+
struct device_node *np)
748750
{
749-
const struct acpm_handle **ptr, *handle;
751+
struct acpm_handle **ptr, *handle;
750752

751753
ptr = devres_alloc(devm_acpm_release, sizeof(*ptr), GFP_KERNEL);
752754
if (!ptr)

drivers/firmware/samsung/exynos-acpm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct acpm_xfer {
1717

1818
struct acpm_handle;
1919

20-
int acpm_do_xfer(const struct acpm_handle *handle,
20+
int acpm_do_xfer(struct acpm_handle *handle,
2121
const struct acpm_xfer *xfer);
2222

2323
#endif /* __EXYNOS_ACPM_H__ */

drivers/mfd/sec-acpm.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ static const struct regmap_config s2mpg11_regmap_config_meter = {
367367
};
368368

369369
struct sec_pmic_acpm_shared_bus_context {
370-
const struct acpm_handle *acpm;
370+
struct acpm_handle *acpm;
371371
unsigned int acpm_chan_id;
372372
u8 speedy_channel;
373373
};
@@ -390,7 +390,7 @@ static int sec_pmic_acpm_bus_write(void *context, const void *data,
390390
size_t count)
391391
{
392392
struct sec_pmic_acpm_bus_context *ctx = context;
393-
const struct acpm_handle *acpm = ctx->shared->acpm;
393+
struct acpm_handle *acpm = ctx->shared->acpm;
394394
const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops;
395395
size_t val_count = count - BITS_TO_BYTES(ACPM_ADDR_BITS);
396396
const u8 *d = data;
@@ -410,7 +410,7 @@ static int sec_pmic_acpm_bus_read(void *context, const void *reg_buf, size_t reg
410410
void *val_buf, size_t val_size)
411411
{
412412
struct sec_pmic_acpm_bus_context *ctx = context;
413-
const struct acpm_handle *acpm = ctx->shared->acpm;
413+
struct acpm_handle *acpm = ctx->shared->acpm;
414414
const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops;
415415
const u8 *r = reg_buf;
416416
u8 reg;
@@ -429,7 +429,7 @@ static int sec_pmic_acpm_bus_reg_update_bits(void *context, unsigned int reg, un
429429
unsigned int val)
430430
{
431431
struct sec_pmic_acpm_bus_context *ctx = context;
432-
const struct acpm_handle *acpm = ctx->shared->acpm;
432+
struct acpm_handle *acpm = ctx->shared->acpm;
433433
const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops;
434434

435435
return pmic_ops->update_reg(acpm, ctx->shared->acpm_chan_id, ctx->type, reg & 0xff,
@@ -480,7 +480,7 @@ static int sec_pmic_acpm_probe(struct platform_device *pdev)
480480
struct regmap *regmap_common, *regmap_pmic, *regmap;
481481
const struct sec_pmic_acpm_platform_data *pdata;
482482
struct sec_pmic_acpm_shared_bus_context *shared_ctx;
483-
const struct acpm_handle *acpm;
483+
struct acpm_handle *acpm;
484484
struct device *dev = &pdev->dev;
485485
int ret, irq;
486486

include/linux/firmware/samsung/exynos-acpm-protocol.h

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,24 @@ struct acpm_handle;
1414
struct device_node;
1515

1616
struct acpm_dvfs_ops {
17-
int (*set_rate)(const struct acpm_handle *handle,
18-
unsigned int acpm_chan_id, unsigned int clk_id,
19-
unsigned long rate);
20-
unsigned long (*get_rate)(const struct acpm_handle *handle,
17+
int (*set_rate)(struct acpm_handle *handle, unsigned int acpm_chan_id,
18+
unsigned int clk_id, unsigned long rate);
19+
unsigned long (*get_rate)(struct acpm_handle *handle,
2120
unsigned int acpm_chan_id,
2221
unsigned int clk_id);
2322
};
2423

2524
struct acpm_pmic_ops {
26-
int (*read_reg)(const struct acpm_handle *handle,
27-
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
28-
u8 *buf);
29-
int (*bulk_read)(const struct acpm_handle *handle,
30-
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
31-
u8 count, u8 *buf);
32-
int (*write_reg)(const struct acpm_handle *handle,
33-
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
34-
u8 value);
35-
int (*bulk_write)(const struct acpm_handle *handle,
36-
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
37-
u8 count, const u8 *buf);
38-
int (*update_reg)(const struct acpm_handle *handle,
39-
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
40-
u8 value, u8 mask);
25+
int (*read_reg)(struct acpm_handle *handle, unsigned int acpm_chan_id,
26+
u8 type, u8 reg, u8 chan, u8 *buf);
27+
int (*bulk_read)(struct acpm_handle *handle, unsigned int acpm_chan_id,
28+
u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
29+
int (*write_reg)(struct acpm_handle *handle, unsigned int acpm_chan_id,
30+
u8 type, u8 reg, u8 chan, u8 value);
31+
int (*bulk_write)(struct acpm_handle *handle, unsigned int acpm_chan_id,
32+
u8 type, u8 reg, u8 chan, u8 count, const u8 *buf);
33+
int (*update_reg)(struct acpm_handle *handle, unsigned int acpm_chan_id,
34+
u8 type, u8 reg, u8 chan, u8 value, u8 mask);
4135
};
4236

4337
struct acpm_ops {
@@ -56,12 +50,12 @@ struct acpm_handle {
5650
struct device;
5751

5852
#if IS_ENABLED(CONFIG_EXYNOS_ACPM_PROTOCOL)
59-
const struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
60-
struct device_node *np);
53+
struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
54+
struct device_node *np);
6155
#else
6256

63-
static inline const struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
64-
struct device_node *np)
57+
static inline struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
58+
struct device_node *np)
6559
{
6660
return NULL;
6761
}

0 commit comments

Comments
 (0)