#include "exynos_ppmu.h"
#include "exynos4_bus.h"
-/* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */
-#ifdef CONFIG_EXYNOS_ASV
-extern unsigned int exynos_result_of_asv;
-#endif
-
#define MAX_SAFEVOLT 1200000 /* 1.2V */
enum exynos4_busf_type {
unsigned long volt;
};
-struct busfreq_ppmu_data {
- struct exynos_ppmu *ppmu;
- int ppmu_end;
-};
-
struct busfreq_data {
enum exynos4_busf_type type;
struct device *dev;
return 0;
}
-static void busfreq_mon_reset(struct busfreq_ppmu_data *ppmu_data)
-{
- unsigned int i;
-
- for (i = 0; i < ppmu_data->ppmu_end; i++) {
- void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base;
-
- /* Reset the performance and cycle counters */
- exynos_ppmu_reset(ppmu_base);
-
- /* Setup count registers to monitor read/write transactions */
- ppmu_data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT;
- exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3,
- ppmu_data->ppmu[i].event[PPMU_PMNCNT3]);
-
- exynos_ppmu_start(ppmu_base);
- }
-}
-
-static void exynos4_read_ppmu(struct busfreq_ppmu_data *ppmu_data)
-{
- int i, j;
-
- for (i = 0; i < ppmu_data->ppmu_end; i++) {
- void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base;
-
- exynos_ppmu_stop(ppmu_base);
-
- /* Update local data from PPMU */
- ppmu_data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT);
-
- for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
- if (ppmu_data->ppmu[i].event[j] == 0)
- ppmu_data->ppmu[i].count[j] = 0;
- else
- ppmu_data->ppmu[i].count[j] =
- exynos_ppmu_read(ppmu_base, j);
- }
- }
-
- busfreq_mon_reset(ppmu_data);
-}
-
static int exynos4x12_get_intspec(unsigned long mifclk)
{
int i = 0;
return err;
}
-static int exynos4_get_busier_ppmu(struct busfreq_ppmu_data *ppmu_data)
-{
- int i, j;
- int busy = 0;
- unsigned int temp = 0;
-
- for (i = 0; i < ppmu_data->ppmu_end; i++) {
- for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
- if (ppmu_data->ppmu[i].count[j] > temp) {
- temp = ppmu_data->ppmu[i].count[j];
- busy = i;
- }
- }
- }
-
- return busy;
-}
-
static int exynos4_bus_get_dev_status(struct device *dev,
struct devfreq_dev_status *stat)
{
struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data;
int busier;
- exynos4_read_ppmu(ppmu_data);
- busier = exynos4_get_busier_ppmu(ppmu_data);
+ exynos_read_ppmu(ppmu_data);
+ busier = exynos_get_busier_ppmu(ppmu_data);
stat->current_frequency = data->curr_oppinfo.rate;
/* Number of cycles spent on memory access */
data->top_divtable[i] = tmp;
}
-#ifdef CONFIG_EXYNOS_ASV
- tmp = exynos4_result_of_asv;
-#else
+ /*
+ * TODO: init tmp based on busfreq_data
+ * (device-tree or platform-data)
+ */
tmp = 0; /* Max voltages for the reliability of the unknown */
-#endif
pr_debug("ASV Group of Exynos4 is %d\n", tmp);
/* Use merged grouping for voltage */
data->dmc_divtable[i] = tmp;
}
-#ifdef CONFIG_EXYNOS_ASV
- tmp = exynos4_result_of_asv;
-#else
tmp = 0; /* Max voltages for the reliability of the unknown */
-#endif
if (tmp > 8)
tmp = 0;
platform_set_drvdata(pdev, data);
- data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile,
+ data->devfreq = devm_devfreq_add_device(dev, &exynos4_devfreq_profile,
"simple_ondemand", NULL);
if (IS_ERR(data->devfreq))
return PTR_ERR(data->devfreq);
busfreq_mon_reset(ppmu_data);
/* Register opp_notifier for Exynos4 busfreq */
- err = devfreq_register_opp_notifier(dev, data->devfreq);
+ err = devm_devfreq_register_opp_notifier(dev, data->devfreq);
if (err < 0) {
dev_err(dev, "Failed to register opp notifier\n");
- goto err_notifier_opp;
+ return err;
}
/* Register pm_notifier for Exynos4 busfreq */
err = register_pm_notifier(&data->pm_notifier);
if (err) {
dev_err(dev, "Failed to setup pm notifier\n");
- goto err_notifier_pm;
+ return err;
}
return 0;
-
-err_notifier_pm:
- devfreq_unregister_opp_notifier(dev, data->devfreq);
-err_notifier_opp:
- devfreq_remove_device(data->devfreq);
-
- return err;
}
static int exynos4_busfreq_remove(struct platform_device *pdev)
/* Unregister all of notifier chain */
unregister_pm_notifier(&data->pm_notifier);
- devfreq_unregister_opp_notifier(data->dev, data->devfreq);
-
- /* Remove devfreq instance */
- devfreq_remove_device(data->devfreq);
return 0;
}