summaryrefslogtreecommitdiffstats
path: root/drivers/clk/at91/pmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/at91/pmc.c')
-rw-r--r--drivers/clk/at91/pmc.c47
1 files changed, 20 insertions, 27 deletions
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 171b62cbfd..f260d08c5d 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -6,6 +6,7 @@
#include <module.h>
#include <linux/list.h>
#include <linux/clkdev.h>
+#include <linux/overflow.h>
#include <of.h>
#include <mfd/syscon.h>
#include <regmap.h>
@@ -63,6 +64,10 @@ struct clk *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
if (idx < pmc_data->ngck)
return pmc_data->ghws[idx];
break;
+ case PMC_TYPE_PROGRAMMABLE:
+ if (idx < pmc_data->npck)
+ return pmc_data->pchws[idx];
+ break;
default:
break;
}
@@ -72,48 +77,34 @@ struct clk *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
return ERR_PTR(-EINVAL);
}
-void pmc_data_free(struct pmc_data *pmc_data)
-{
- kfree(pmc_data->chws);
- kfree(pmc_data->shws);
- kfree(pmc_data->phws);
- kfree(pmc_data->ghws);
-}
-
struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
- unsigned int nperiph, unsigned int ngck)
+ unsigned int nperiph, unsigned int ngck,
+ unsigned int npck)
{
- struct pmc_data *pmc_data = kzalloc(sizeof(*pmc_data), GFP_KERNEL);
+ unsigned int num_clks = ncore + nsystem + nperiph + ngck + npck;
+ struct pmc_data *pmc_data;
+ pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks),
+ GFP_KERNEL);
if (!pmc_data)
return NULL;
pmc_data->ncore = ncore;
- pmc_data->chws = kcalloc(ncore, sizeof(struct clk *), GFP_KERNEL);
- if (!pmc_data->chws)
- goto err;
+ pmc_data->chws = pmc_data->hwtable;
pmc_data->nsystem = nsystem;
- pmc_data->shws = kcalloc(nsystem, sizeof(struct clk *), GFP_KERNEL);
- if (!pmc_data->shws)
- goto err;
+ pmc_data->shws = pmc_data->chws + ncore;
pmc_data->nperiph = nperiph;
- pmc_data->phws = kcalloc(nperiph, sizeof(struct clk *), GFP_KERNEL);
- if (!pmc_data->phws)
- goto err;
+ pmc_data->phws = pmc_data->shws + nsystem;
pmc_data->ngck = ngck;
- pmc_data->ghws = kcalloc(ngck, sizeof(struct clk *), GFP_KERNEL);
- if (!pmc_data->ghws)
- goto err;
+ pmc_data->ghws = pmc_data->phws + nperiph;
- return pmc_data;
-
-err:
- pmc_data_free(pmc_data);
+ pmc_data->npck = npck;
+ pmc_data->pchws = pmc_data->ghws + ngck;
- return NULL;
+ return pmc_data;
}
#ifdef CONFIG_PM
@@ -270,6 +261,8 @@ static int __init pmc_register_ops(void)
struct device_node *np;
np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
+ if (!np)
+ return -ENODEV;
pmcreg = device_node_to_regmap(np);
if (IS_ERR(pmcreg))