Commit b1cd0639 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'ti-driver-soc-for-v6.12' of...

Merge tag 'ti-driver-soc-for-v6.12' of https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux into soc/drivers

TI SoC driver updates for v6.12

- pm33xx/knav_qmss_queue/pruss: Cleanups around device_node scope based cleanups
- knav: Additional fixes around of property
- k3-ringacc: Optimizations for data structure

* tag 'ti-driver-soc-for-v6.12' of https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux:
  soc: ti: pm33xx: do device_node auto cleanup
  soc: ti: knav_qmss_queue: do device_node auto cleanup
  soc: ti: pruss: do device_node auto cleanup
  soc: ti: pruss: factor out memories setup
  soc: ti: knav: Use of_property_read_variable_u32_array()
  soc: ti: knav: Drop unnecessary check for property presence
  soc: ti: k3-ringacc: Constify struct k3_ring_ops

Link: https://lore.kernel.org/r/20240903155632.525twuumykwnfkiz@subtitleSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents d205c06a 68123510
......@@ -161,7 +161,7 @@ struct k3_ring {
struct k3_ringacc_proxy_target_regs __iomem *proxy;
dma_addr_t ring_mem_dma;
void *ring_mem_virt;
struct k3_ring_ops *ops;
const struct k3_ring_ops *ops;
u32 size;
enum k3_ring_size elm_size;
enum k3_ring_mode mode;
......@@ -268,17 +268,17 @@ static int k3_ringacc_ring_pop_mem(struct k3_ring *ring, void *elem);
static int k3_dmaring_fwd_pop(struct k3_ring *ring, void *elem);
static int k3_dmaring_reverse_pop(struct k3_ring *ring, void *elem);
static struct k3_ring_ops k3_ring_mode_ring_ops = {
static const struct k3_ring_ops k3_ring_mode_ring_ops = {
.push_tail = k3_ringacc_ring_push_mem,
.pop_head = k3_ringacc_ring_pop_mem,
};
static struct k3_ring_ops k3_dmaring_fwd_ops = {
static const struct k3_ring_ops k3_dmaring_fwd_ops = {
.push_tail = k3_ringacc_ring_push_mem,
.pop_head = k3_dmaring_fwd_pop,
};
static struct k3_ring_ops k3_dmaring_reverse_ops = {
static const struct k3_ring_ops k3_dmaring_reverse_ops = {
/* Reverse side of the DMA ring can only be popped by SW */
.pop_head = k3_dmaring_reverse_pop,
};
......@@ -288,7 +288,7 @@ static int k3_ringacc_ring_pop_io(struct k3_ring *ring, void *elem);
static int k3_ringacc_ring_push_head_io(struct k3_ring *ring, void *elem);
static int k3_ringacc_ring_pop_tail_io(struct k3_ring *ring, void *elem);
static struct k3_ring_ops k3_ring_mode_msg_ops = {
static const struct k3_ring_ops k3_ring_mode_msg_ops = {
.push_tail = k3_ringacc_ring_push_io,
.push_head = k3_ringacc_ring_push_head_io,
.pop_tail = k3_ringacc_ring_pop_tail_io,
......@@ -300,7 +300,7 @@ static int k3_ringacc_ring_push_tail_proxy(struct k3_ring *ring, void *elem);
static int k3_ringacc_ring_pop_head_proxy(struct k3_ring *ring, void *elem);
static int k3_ringacc_ring_pop_tail_proxy(struct k3_ring *ring, void *elem);
static struct k3_ring_ops k3_ring_mode_proxy_ops = {
static const struct k3_ring_ops k3_ring_mode_proxy_ops = {
.push_tail = k3_ringacc_ring_push_tail_proxy,
.push_head = k3_ringacc_ring_push_head_proxy,
.pop_tail = k3_ringacc_ring_pop_tail_proxy,
......
......@@ -602,7 +602,7 @@ static int dma_init(struct device_node *cloud, struct device_node *dma_node)
unsigned max_tx_chan, max_rx_chan, max_rx_flow, max_tx_sched;
struct device_node *node = dma_node;
struct knav_dma_device *dma;
int ret, len, num_chan = 0;
int ret, num_chan = 0;
resource_size_t size;
u32 timeout;
u32 i;
......@@ -615,25 +615,13 @@ static int dma_init(struct device_node *cloud, struct device_node *dma_node)
INIT_LIST_HEAD(&dma->list);
INIT_LIST_HEAD(&dma->chan_list);
if (!of_find_property(cloud, "ti,navigator-cloud-address", &len)) {
dev_err(kdev->dev, "unspecified navigator cloud addresses\n");
return -ENODEV;
}
dma->logical_queue_managers = len / sizeof(u32);
if (dma->logical_queue_managers > DMA_MAX_QMS) {
dev_warn(kdev->dev, "too many queue mgrs(>%d) rest ignored\n",
dma->logical_queue_managers);
dma->logical_queue_managers = DMA_MAX_QMS;
}
ret = of_property_read_u32_array(cloud, "ti,navigator-cloud-address",
dma->qm_base_address,
dma->logical_queue_managers);
if (ret) {
ret = of_property_read_variable_u32_array(cloud, "ti,navigator-cloud-address",
dma->qm_base_address, 1, DMA_MAX_QMS);
if (ret < 0) {
dev_err(kdev->dev, "invalid navigator cloud addresses\n");
return -ENODEV;
}
dma->logical_queue_managers = ret;
dma->reg_global = pktdma_get_regs(dma, node, 0, &size);
if (IS_ERR(dma->reg_global))
......
......@@ -1076,14 +1076,20 @@ static const char *knav_queue_find_name(struct device_node *node)
}
static int knav_queue_setup_regions(struct knav_device *kdev,
struct device_node *regions)
struct device_node *node)
{
struct device *dev = kdev->dev;
struct device_node *regions __free(device_node) =
of_get_child_by_name(node, "descriptor-regions");
struct knav_region *region;
struct device_node *child;
u32 temp[2];
int ret;
if (!regions)
return dev_err_probe(dev, -ENODEV,
"descriptor-regions not specified\n");
for_each_child_of_node(regions, child) {
region = devm_kzalloc(dev, sizeof(*region), GFP_KERNEL);
if (!region) {
......@@ -1104,11 +1110,6 @@ static int knav_queue_setup_regions(struct knav_device *kdev,
continue;
}
if (!of_get_property(child, "link-index", NULL)) {
dev_err(dev, "No link info for %s\n", region->name);
devm_kfree(dev, region);
continue;
}
ret = of_property_read_u32(child, "link-index",
&region->link_index);
if (ret) {
......@@ -1121,10 +1122,9 @@ static int knav_queue_setup_regions(struct knav_device *kdev,
INIT_LIST_HEAD(&region->pools);
list_add_tail(&region->list, &kdev->regions);
}
if (list_empty(&kdev->regions)) {
dev_err(dev, "no valid region information found\n");
return -ENODEV;
}
if (list_empty(&kdev->regions))
return dev_err_probe(dev, -ENODEV,
"no valid region information found\n");
/* Next, we run through the regions and set things up */
for_each_region(kdev, region)
......@@ -1306,10 +1306,16 @@ static int knav_setup_queue_range(struct knav_device *kdev,
}
static int knav_setup_queue_pools(struct knav_device *kdev,
struct device_node *queue_pools)
struct device_node *node)
{
struct device_node *queue_pools __free(device_node) =
of_get_child_by_name(node, "queue-pools");
struct device_node *type, *range;
if (!queue_pools)
return dev_err_probe(kdev->dev, -ENODEV,
"queue-pools not specified\n");
for_each_child_of_node(queue_pools, type) {
for_each_child_of_node(type, range) {
/* return value ignored, we init the rest... */
......@@ -1318,10 +1324,9 @@ static int knav_setup_queue_pools(struct knav_device *kdev,
}
/* ... and barf if they all failed! */
if (list_empty(&kdev->queue_ranges)) {
dev_err(kdev->dev, "no valid queue range found\n");
return -ENODEV;
}
if (list_empty(&kdev->queue_ranges))
return dev_err_probe(kdev->dev, -ENODEV,
"no valid queue range found\n");
return 0;
}
......@@ -1389,14 +1394,20 @@ static void __iomem *knav_queue_map_reg(struct knav_device *kdev,
}
static int knav_queue_init_qmgrs(struct knav_device *kdev,
struct device_node *qmgrs)
struct device_node *node)
{
struct device *dev = kdev->dev;
struct device_node *qmgrs __free(device_node) =
of_get_child_by_name(node, "qmgrs");
struct knav_qmgr_info *qmgr;
struct device_node *child;
u32 temp[2];
int ret;
if (!qmgrs)
return dev_err_probe(dev, -ENODEV,
"queue manager info not specified\n");
for_each_child_of_node(qmgrs, child) {
qmgr = devm_kzalloc(dev, sizeof(*qmgr), GFP_KERNEL);
if (!qmgr) {
......@@ -1668,6 +1679,26 @@ static int knav_queue_start_pdsps(struct knav_device *kdev)
return 0;
}
static int knav_queue_setup_pdsps(struct knav_device *kdev,
struct device_node *node)
{
struct device_node *pdsps __free(device_node) =
of_get_child_by_name(node, "pdsps");
if (pdsps) {
int ret;
ret = knav_queue_init_pdsps(kdev, pdsps);
if (ret)
return ret;
ret = knav_queue_start_pdsps(kdev);
if (ret)
return ret;
}
return 0;
}
static inline struct knav_qmgr_info *knav_find_qmgr(unsigned id)
{
struct knav_qmgr_info *qmgr;
......@@ -1755,7 +1786,6 @@ MODULE_DEVICE_TABLE(of, keystone_qmss_of_match);
static int knav_queue_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct device_node *qmgrs, *queue_pools, *regions, *pdsps;
struct device *dev = &pdev->dev;
u32 temp[2];
int ret;
......@@ -1799,39 +1829,17 @@ static int knav_queue_probe(struct platform_device *pdev)
kdev->num_queues = temp[1];
/* Initialize queue managers using device tree configuration */
qmgrs = of_get_child_by_name(node, "qmgrs");
if (!qmgrs) {
dev_err(dev, "queue manager info not specified\n");
ret = -ENODEV;
goto err;
}
ret = knav_queue_init_qmgrs(kdev, qmgrs);
of_node_put(qmgrs);
ret = knav_queue_init_qmgrs(kdev, node);
if (ret)
goto err;
/* get pdsp configuration values from device tree */
pdsps = of_get_child_by_name(node, "pdsps");
if (pdsps) {
ret = knav_queue_init_pdsps(kdev, pdsps);
if (ret)
goto err;
ret = knav_queue_start_pdsps(kdev);
if (ret)
goto err;
}
of_node_put(pdsps);
ret = knav_queue_setup_pdsps(kdev, node);
if (ret)
goto err;
/* get usable queue range values from device tree */
queue_pools = of_get_child_by_name(node, "queue-pools");
if (!queue_pools) {
dev_err(dev, "queue-pools not specified\n");
ret = -ENODEV;
goto err;
}
ret = knav_setup_queue_pools(kdev, queue_pools);
of_node_put(queue_pools);
ret = knav_setup_queue_pools(kdev, node);
if (ret)
goto err;
......@@ -1853,14 +1861,7 @@ static int knav_queue_probe(struct platform_device *pdev)
if (ret)
goto err;
regions = of_get_child_by_name(node, "descriptor-regions");
if (!regions) {
dev_err(dev, "descriptor-regions not specified\n");
ret = -ENODEV;
goto err;
}
ret = knav_queue_setup_regions(kdev, regions);
of_node_put(regions);
ret = knav_queue_setup_regions(kdev, node);
if (ret)
goto err;
......
......@@ -383,54 +383,44 @@ static void am33xx_pm_free_sram(void)
*/
static int am33xx_pm_alloc_sram(void)
{
struct device_node *np;
int ret = 0;
struct device_node *np __free(device_node) =
of_find_compatible_node(NULL, NULL, "ti,omap3-mpu");
np = of_find_compatible_node(NULL, NULL, "ti,omap3-mpu");
if (!np) {
np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
if (!np) {
dev_err(pm33xx_dev, "PM: %s: Unable to find device node for mpu\n",
__func__);
return -ENODEV;
}
if (!np)
return dev_err_probe(pm33xx_dev, -ENODEV,
"PM: %s: Unable to find device node for mpu\n",
__func__);
}
sram_pool = of_gen_pool_get(np, "pm-sram", 0);
if (!sram_pool) {
dev_err(pm33xx_dev, "PM: %s: Unable to get sram pool for ocmcram\n",
__func__);
ret = -ENODEV;
goto mpu_put_node;
}
if (!sram_pool)
return dev_err_probe(pm33xx_dev, -ENODEV,
"PM: %s: Unable to get sram pool for ocmcram\n",
__func__);
sram_pool_data = of_gen_pool_get(np, "pm-sram", 1);
if (!sram_pool_data) {
dev_err(pm33xx_dev, "PM: %s: Unable to get sram data pool for ocmcram\n",
__func__);
ret = -ENODEV;
goto mpu_put_node;
}
if (!sram_pool_data)
return dev_err_probe(pm33xx_dev, -ENODEV,
"PM: %s: Unable to get sram data pool for ocmcram\n",
__func__);
ocmcram_location = gen_pool_alloc(sram_pool, *pm_sram->do_wfi_sz);
if (!ocmcram_location) {
dev_err(pm33xx_dev, "PM: %s: Unable to allocate memory from ocmcram\n",
__func__);
ret = -ENOMEM;
goto mpu_put_node;
}
if (!ocmcram_location)
return dev_err_probe(pm33xx_dev, -ENOMEM,
"PM: %s: Unable to allocate memory from ocmcram\n",
__func__);
ocmcram_location_data = gen_pool_alloc(sram_pool_data,
sizeof(struct emif_regs_amx3));
if (!ocmcram_location_data) {
dev_err(pm33xx_dev, "PM: Unable to allocate memory from ocmcram\n");
gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);
ret = -ENOMEM;
return dev_err_probe(pm33xx_dev, -ENOMEM,
"PM: Unable to allocate memory from ocmcram\n");
}
mpu_put_node:
of_node_put(np);
return ret;
return 0;
}
static int am33xx_pm_rtc_setup(void)
......
......@@ -380,39 +380,81 @@ static int pruss_clk_mux_setup(struct pruss *pruss, struct clk *clk_mux,
static int pruss_clk_init(struct pruss *pruss, struct device_node *cfg_node)
{
const struct pruss_private_data *data;
struct device_node *clks_np;
struct device *dev = pruss->dev;
int ret = 0;
data = of_device_get_match_data(dev);
struct device_node *clks_np __free(device_node) =
of_get_child_by_name(cfg_node, "clocks");
const struct pruss_private_data *data = of_device_get_match_data(dev);
int ret;
clks_np = of_get_child_by_name(cfg_node, "clocks");
if (!clks_np) {
dev_err(dev, "%pOF is missing its 'clocks' node\n", cfg_node);
return -ENODEV;
}
if (!clks_np)
return dev_err_probe(dev, -ENODEV,
"%pOF is missing its 'clocks' node\n",
cfg_node);
if (data && data->has_core_mux_clock) {
ret = pruss_clk_mux_setup(pruss, pruss->core_clk_mux,
"coreclk-mux", clks_np);
if (ret) {
dev_err(dev, "failed to setup coreclk-mux\n");
goto put_clks_node;
}
if (ret)
return dev_err_probe(dev, ret,
"failed to setup coreclk-mux\n");
}
ret = pruss_clk_mux_setup(pruss, pruss->iep_clk_mux, "iepclk-mux",
clks_np);
if (ret) {
dev_err(dev, "failed to setup iepclk-mux\n");
goto put_clks_node;
}
if (ret)
return dev_err_probe(dev, ret, "failed to setup iepclk-mux\n");
put_clks_node:
of_node_put(clks_np);
return 0;
}
return ret;
static int pruss_of_setup_memories(struct device *dev, struct pruss *pruss)
{
struct device_node *np = dev_of_node(dev);
struct device_node *child __free(device_node) =
of_get_child_by_name(np, "memories");
const struct pruss_private_data *data = of_device_get_match_data(dev);
const char *mem_names[PRUSS_MEM_MAX] = { "dram0", "dram1", "shrdram2" };
int i;
if (!child)
return dev_err_probe(dev, -ENODEV,
"%pOF is missing its 'memories' node\n",
child);
for (i = 0; i < PRUSS_MEM_MAX; i++) {
struct resource res;
int index;
/*
* On AM437x one of two PRUSS units don't contain Shared RAM,
* skip it
*/
if (data && data->has_no_sharedram && i == PRUSS_MEM_SHRD_RAM2)
continue;
index = of_property_match_string(child, "reg-names",
mem_names[i]);
if (index < 0)
return index;
if (of_address_to_resource(child, index, &res))
return -EINVAL;
pruss->mem_regions[i].va = devm_ioremap(dev, res.start,
resource_size(&res));
if (!pruss->mem_regions[i].va)
return dev_err_probe(dev, -ENOMEM,
"failed to parse and map memory resource %d %s\n",
i, mem_names[i]);
pruss->mem_regions[i].pa = res.start;
pruss->mem_regions[i].size = resource_size(&res);
dev_dbg(dev, "memory %8s: pa %pa size 0x%zx va %pK\n",
mem_names[i], &pruss->mem_regions[i].pa,
pruss->mem_regions[i].size, pruss->mem_regions[i].va);
}
return 0;
}
static struct regmap_config regmap_conf = {
......@@ -424,26 +466,21 @@ static struct regmap_config regmap_conf = {
static int pruss_cfg_of_init(struct device *dev, struct pruss *pruss)
{
struct device_node *np = dev_of_node(dev);
struct device_node *child;
struct device_node *child __free(device_node) =
of_get_child_by_name(np, "cfg");
struct resource res;
int ret;
child = of_get_child_by_name(np, "cfg");
if (!child) {
dev_err(dev, "%pOF is missing its 'cfg' node\n", child);
return -ENODEV;
}
if (!child)
return dev_err_probe(dev, -ENODEV,
"%pOF is missing its 'cfg' node\n", child);
if (of_address_to_resource(child, 0, &res)) {
ret = -ENOMEM;
goto node_put;
}
if (of_address_to_resource(child, 0, &res))
return -ENOMEM;
pruss->cfg_base = devm_ioremap(dev, res.start, resource_size(&res));
if (!pruss->cfg_base) {
ret = -ENOMEM;
goto node_put;
}
if (!pruss->cfg_base)
return -ENOMEM;
regmap_conf.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", child,
(u64)res.start);
......@@ -452,34 +489,22 @@ static int pruss_cfg_of_init(struct device *dev, struct pruss *pruss)
pruss->cfg_regmap = devm_regmap_init_mmio(dev, pruss->cfg_base,
&regmap_conf);
kfree(regmap_conf.name);
if (IS_ERR(pruss->cfg_regmap)) {
dev_err(dev, "regmap_init_mmio failed for cfg, ret = %ld\n",
PTR_ERR(pruss->cfg_regmap));
ret = PTR_ERR(pruss->cfg_regmap);
goto node_put;
}
if (IS_ERR(pruss->cfg_regmap))
return dev_err_probe(dev, PTR_ERR(pruss->cfg_regmap),
"regmap_init_mmio failed for cfg\n");
ret = pruss_clk_init(pruss, child);
if (ret)
dev_err(dev, "pruss_clk_init failed, ret = %d\n", ret);
return dev_err_probe(dev, ret, "pruss_clk_init failed\n");
node_put:
of_node_put(child);
return ret;
return 0;
}
static int pruss_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev_of_node(dev);
struct device_node *child;
struct pruss *pruss;
struct resource res;
int ret, i, index;
const struct pruss_private_data *data;
const char *mem_names[PRUSS_MEM_MAX] = { "dram0", "dram1", "shrdram2" };
data = of_device_get_match_data(&pdev->dev);
int ret;
ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
if (ret) {
......@@ -494,48 +519,9 @@ static int pruss_probe(struct platform_device *pdev)
pruss->dev = dev;
mutex_init(&pruss->lock);
child = of_get_child_by_name(np, "memories");
if (!child) {
dev_err(dev, "%pOF is missing its 'memories' node\n", child);
return -ENODEV;
}
for (i = 0; i < PRUSS_MEM_MAX; i++) {
/*
* On AM437x one of two PRUSS units don't contain Shared RAM,
* skip it
*/
if (data && data->has_no_sharedram && i == PRUSS_MEM_SHRD_RAM2)
continue;
index = of_property_match_string(child, "reg-names",
mem_names[i]);
if (index < 0) {
of_node_put(child);
return index;
}
if (of_address_to_resource(child, index, &res)) {
of_node_put(child);
return -EINVAL;
}
pruss->mem_regions[i].va = devm_ioremap(dev, res.start,
resource_size(&res));
if (!pruss->mem_regions[i].va) {
dev_err(dev, "failed to parse and map memory resource %d %s\n",
i, mem_names[i]);
of_node_put(child);
return -ENOMEM;
}
pruss->mem_regions[i].pa = res.start;
pruss->mem_regions[i].size = resource_size(&res);
dev_dbg(dev, "memory %8s: pa %pa size 0x%zx va %pK\n",
mem_names[i], &pruss->mem_regions[i].pa,
pruss->mem_regions[i].size, pruss->mem_regions[i].va);
}
of_node_put(child);
ret = pruss_of_setup_memories(dev, pruss);
if (ret < 0)
return ret;
platform_set_drvdata(pdev, pruss);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment