#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pl320-ipc.h>
#include <linux/platform_device.h>
#define HB_CPUFREQ_CHANGE_NOTE 0x80000001
#define HB_CPUFREQ_IPC_LEN 7
#define HB_CPUFREQ_VOLT_RETRIES 15
static int hb_voltage_change(unsigned int freq)
u32 msg[HB_CPUFREQ_IPC_LEN] = {HB_CPUFREQ_CHANGE_NOTE, freq / 1000000};
return pl320_ipc_transmit(msg);
static int hb_cpufreq_clk_notify(struct notifier_block *nb,
unsigned long action, void *hclk)
struct clk_notifier_data *clk_data = hclk;
if (action == PRE_RATE_CHANGE) {
if (clk_data->new_rate > clk_data->old_rate)
while (hb_voltage_change(clk_data->new_rate))
if (i++ > HB_CPUFREQ_VOLT_RETRIES)
} else if (action == POST_RATE_CHANGE) {
if (clk_data->new_rate < clk_data->old_rate)
while (hb_voltage_change(clk_data->new_rate))
if (i++ > HB_CPUFREQ_VOLT_RETRIES)
static struct notifier_block hb_cpufreq_clk_nb = {
.notifier_call = hb_cpufreq_clk_notify,
static int hb_cpufreq_driver_init(void)
struct platform_device_info devinfo = { .name = "cpufreq-dt", };