mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
soc: sunxi: sram: Support claiming multiple regions per device
On the H616, the video engine needs to claim two SRAM regions. Support claiming multiple regions per device. Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com> Link: https://patch.msgid.link/20260324164357.1607247-6-wens@kernel.org Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
This commit is contained in:
parent
67890da74d
commit
be99eb936b
|
|
@ -165,79 +165,48 @@ static inline struct sunxi_sram_desc *to_sram_desc(const struct sunxi_sram_data
|
|||
return container_of(data, struct sunxi_sram_desc, data);
|
||||
}
|
||||
|
||||
static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *node,
|
||||
unsigned int *reg_value)
|
||||
static const struct sunxi_sram_data *sunxi_sram_get_match(struct device_node *np, u8 val,
|
||||
unsigned int *reg_value)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
const struct sunxi_sram_data *data;
|
||||
const struct sunxi_sram_func *func;
|
||||
struct of_phandle_args args;
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ret = of_parse_phandle_with_fixed_args(node, "allwinner,sram", 1, 0,
|
||||
&args);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
if (!of_device_is_available(np))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
if (!of_device_is_available(args.np)) {
|
||||
ret = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
val = args.args[0];
|
||||
|
||||
match = of_match_node(sunxi_sram_dt_ids, args.np);
|
||||
if (!match) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
match = of_match_node(sunxi_sram_dt_ids, np);
|
||||
if (!match)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
data = match->data;
|
||||
if (!data) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (func = data->func; func->func; func++) {
|
||||
if (val == func->val) {
|
||||
if (reg_value)
|
||||
*reg_value = func->reg_val;
|
||||
if (!data)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
for (func = data->func; func->func; func++)
|
||||
if (val == func->val)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!func->func) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
if (!func->func)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
of_node_put(args.np);
|
||||
return match->data;
|
||||
if (reg_value)
|
||||
*reg_value = func->reg_val;
|
||||
|
||||
err:
|
||||
of_node_put(args.np);
|
||||
return ERR_PTR(ret);
|
||||
return data;
|
||||
}
|
||||
|
||||
int sunxi_sram_claim(struct device *dev)
|
||||
#define SUNXI_SRAM_PROP "allwinner,sram"
|
||||
#define SUNXI_SRAM_CELLS 1
|
||||
|
||||
static int sunxi_sram_claim_one(struct device_node *np, u8 arg)
|
||||
{
|
||||
const struct sunxi_sram_data *sram_data;
|
||||
struct sunxi_sram_desc *sram_desc;
|
||||
unsigned int device;
|
||||
u32 val, mask;
|
||||
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
if (!base)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (!dev || !dev->of_node)
|
||||
return -EINVAL;
|
||||
|
||||
sram_data = sunxi_sram_of_parse(dev->of_node, &device);
|
||||
sram_data = sunxi_sram_get_match(np, arg, &device);
|
||||
if (IS_ERR(sram_data))
|
||||
return PTR_ERR(sram_data);
|
||||
|
||||
|
|
@ -248,33 +217,28 @@ int sunxi_sram_claim(struct device *dev)
|
|||
if (sram_desc->claim_cnt) {
|
||||
if (!WARN_ON(sram_desc->claim_cnt == U8_MAX))
|
||||
sram_desc->claim_cnt++;
|
||||
spin_unlock(&sram_lock);
|
||||
return 0;
|
||||
} else {
|
||||
mask = GENMASK(sram_data->offset + sram_data->width - 1,
|
||||
sram_data->offset);
|
||||
val = readl(base + sram_data->reg);
|
||||
val &= ~mask;
|
||||
writel(val | ((device << sram_data->offset) & mask),
|
||||
base + sram_data->reg);
|
||||
|
||||
sram_desc->claim_cnt++;
|
||||
}
|
||||
|
||||
mask = GENMASK(sram_data->offset + sram_data->width - 1,
|
||||
sram_data->offset);
|
||||
val = readl(base + sram_data->reg);
|
||||
val &= ~mask;
|
||||
writel(val | ((device << sram_data->offset) & mask),
|
||||
base + sram_data->reg);
|
||||
|
||||
sram_desc->claim_cnt++;
|
||||
spin_unlock(&sram_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(sunxi_sram_claim);
|
||||
|
||||
void sunxi_sram_release(struct device *dev)
|
||||
static void sunxi_sram_release_one(struct device_node *np, u8 arg)
|
||||
{
|
||||
const struct sunxi_sram_data *sram_data;
|
||||
struct sunxi_sram_desc *sram_desc;
|
||||
|
||||
if (!dev || !dev->of_node)
|
||||
return;
|
||||
|
||||
sram_data = sunxi_sram_of_parse(dev->of_node, NULL);
|
||||
sram_data = sunxi_sram_get_match(np, arg, NULL);
|
||||
if (IS_ERR(sram_data))
|
||||
return;
|
||||
|
||||
|
|
@ -285,6 +249,70 @@ void sunxi_sram_release(struct device *dev)
|
|||
sram_desc->claim_cnt--;
|
||||
spin_unlock(&sram_lock);
|
||||
}
|
||||
|
||||
int sunxi_sram_claim(struct device *dev)
|
||||
{
|
||||
struct of_phandle_iterator it;
|
||||
int err;
|
||||
int count = 0;
|
||||
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
if (!base)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (!dev || !dev->of_node)
|
||||
return -EINVAL;
|
||||
|
||||
of_for_each_phandle(&it, err, dev->of_node, SUNXI_SRAM_PROP,
|
||||
NULL, SUNXI_SRAM_CELLS) {
|
||||
u32 args[SUNXI_SRAM_CELLS];
|
||||
|
||||
of_phandle_iterator_args(&it, args, SUNXI_SRAM_CELLS);
|
||||
|
||||
err = sunxi_sram_claim_one(it.node, args[0]);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
return -ENOENT;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
while (count--) {
|
||||
struct of_phandle_args args;
|
||||
|
||||
of_parse_phandle_with_fixed_args(dev->of_node, SUNXI_SRAM_PROP,
|
||||
SUNXI_SRAM_CELLS, count, &args);
|
||||
sunxi_sram_release_one(args.np, args.args[0]);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(sunxi_sram_claim);
|
||||
|
||||
void sunxi_sram_release(struct device *dev)
|
||||
{
|
||||
struct of_phandle_iterator it;
|
||||
int err;
|
||||
|
||||
if (!dev || !dev->of_node)
|
||||
return;
|
||||
|
||||
of_for_each_phandle(&it, err, dev->of_node, SUNXI_SRAM_PROP,
|
||||
NULL, SUNXI_SRAM_CELLS) {
|
||||
u32 args[SUNXI_SRAM_CELLS];
|
||||
|
||||
of_phandle_iterator_args(&it, args, SUNXI_SRAM_CELLS);
|
||||
|
||||
sunxi_sram_release_one(it.node, args[0]);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(sunxi_sram_release);
|
||||
|
||||
struct sunxi_sramc_variant {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user