^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Generic Exynos Bus frequency driver with DEVFREQ Framework
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2016 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author : Chanwoo Choi <cw00.choi@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This driver support Exynos Bus frequency feature by using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * DEVFREQ framework and is based on drivers/devfreq/exynos/exynos4_bus.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/devfreq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/devfreq-event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/pm_opp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define DEFAULT_SATURATION_RATIO 40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct exynos_bus {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct devfreq *devfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct devfreq_event_dev **edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned int edev_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned long curr_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct opp_table *opp_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned int ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Control the devfreq-event device to get the current state of bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define exynos_bus_ops_edev(ops) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int exynos_bus_##ops(struct exynos_bus *bus) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int i, ret; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) for (i = 0; i < bus->edev_count; i++) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (!bus->edev[i]) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) continue; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ret = devfreq_event_##ops(bus->edev[i]); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (ret < 0) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return ret; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) exynos_bus_ops_edev(enable_edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) exynos_bus_ops_edev(disable_edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) exynos_bus_ops_edev(set_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int exynos_bus_get_event(struct exynos_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct devfreq_event_data *edata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct devfreq_event_data event_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned long load_count = 0, total_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) for (i = 0; i < bus->edev_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (!bus->edev[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ret = devfreq_event_get_event(bus->edev[i], &event_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (i == 0 || event_data.load_count > load_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) load_count = event_data.load_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) total_count = event_data.total_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) edata->load_count = load_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) edata->total_count = total_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * devfreq function for both simple-ondemand and passive governor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct exynos_bus *bus = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct dev_pm_opp *new_opp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Get correct frequency for bus. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) new_opp = devfreq_recommended_opp(dev, freq, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (IS_ERR(new_opp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) dev_err(dev, "failed to get recommended opp instance\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return PTR_ERR(new_opp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) dev_pm_opp_put(new_opp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Change voltage and frequency according to new OPP level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) mutex_lock(&bus->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ret = dev_pm_opp_set_rate(dev, *freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) bus->curr_freq = *freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) mutex_unlock(&bus->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static int exynos_bus_get_dev_status(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct devfreq_dev_status *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct exynos_bus *bus = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct devfreq_event_data edata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) stat->current_frequency = bus->curr_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ret = exynos_bus_get_event(bus, &edata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dev_err(dev, "failed to get event from devfreq-event devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) stat->total_time = stat->busy_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) stat->busy_time = (edata.load_count * 100) / bus->ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) stat->total_time = edata.total_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) dev_dbg(dev, "Usage of devfreq-event : %lu/%lu\n", stat->busy_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) stat->total_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ret = exynos_bus_set_event(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) dev_err(dev, "failed to set event to devfreq-event devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static void exynos_bus_exit(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct exynos_bus *bus = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ret = exynos_bus_disable_edev(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) dev_warn(dev, "failed to disable the devfreq-event devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dev_pm_opp_of_remove_table(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) clk_disable_unprepare(bus->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (bus->opp_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) dev_pm_opp_put_regulators(bus->opp_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) bus->opp_table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static void exynos_bus_passive_exit(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct exynos_bus *bus = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) dev_pm_opp_of_remove_table(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) clk_disable_unprepare(bus->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int exynos_bus_parent_parse_of(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct exynos_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct device *dev = bus->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct opp_table *opp_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) const char *vdd = "vdd";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int i, ret, count, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) opp_table = dev_pm_opp_set_regulators(dev, &vdd, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (IS_ERR(opp_table)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ret = PTR_ERR(opp_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) dev_err(dev, "failed to set regulators %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) bus->opp_table = opp_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * Get the devfreq-event devices to get the current utilization of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * buses. This raw data will be used in devfreq ondemand governor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) count = devfreq_event_get_edev_count(dev, "devfreq-events");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (count < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dev_err(dev, "failed to get the count of devfreq-event dev\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) goto err_regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) bus->edev_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) size = sizeof(*bus->edev) * count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) bus->edev = devm_kzalloc(dev, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (!bus->edev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) goto err_regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) bus->edev[i] = devfreq_event_get_edev_by_phandle(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) "devfreq-events", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (IS_ERR(bus->edev[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ret = -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) goto err_regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * Optionally, Get the saturation ratio according to Exynos SoC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * When measuring the utilization of each AXI bus with devfreq-event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * devices, the measured real cycle might be much lower than the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * total cycle of bus during sampling rate. In result, the devfreq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * simple-ondemand governor might not decide to change the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * frequency due to too utilization (= real cycle/total cycle).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * So, this property is used to adjust the utilization when calculating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * the busy_time in exynos_bus_get_dev_status().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (of_property_read_u32(np, "exynos,saturation-ratio", &bus->ratio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) bus->ratio = DEFAULT_SATURATION_RATIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) err_regulator:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) dev_pm_opp_put_regulators(bus->opp_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) bus->opp_table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int exynos_bus_parse_of(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct exynos_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct device *dev = bus->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct dev_pm_opp *opp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* Get the clock to provide each bus with source clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) bus->clk = devm_clk_get(dev, "bus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (IS_ERR(bus->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) dev_err(dev, "failed to get bus clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return PTR_ERR(bus->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = clk_prepare_enable(bus->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dev_err(dev, "failed to get enable clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Get the freq and voltage from OPP table to scale the bus freq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ret = dev_pm_opp_of_add_table(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dev_err(dev, "failed to get OPP table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) rate = clk_get_rate(bus->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) opp = devfreq_recommended_opp(dev, &rate, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (IS_ERR(opp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dev_err(dev, "failed to find dev_pm_opp\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ret = PTR_ERR(opp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) goto err_opp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) bus->curr_freq = dev_pm_opp_get_freq(opp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) dev_pm_opp_put(opp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) err_opp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) dev_pm_opp_of_remove_table(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) err_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) clk_disable_unprepare(bus->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int exynos_bus_profile_init(struct exynos_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct devfreq_dev_profile *profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct device *dev = bus->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct devfreq_simple_ondemand_data *ondemand_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* Initialize the struct profile and governor data for parent device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) profile->polling_ms = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) profile->target = exynos_bus_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) profile->get_dev_status = exynos_bus_get_dev_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) profile->exit = exynos_bus_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ondemand_data = devm_kzalloc(dev, sizeof(*ondemand_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!ondemand_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ondemand_data->upthreshold = 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ondemand_data->downdifferential = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Add devfreq device to monitor and handle the exynos bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) bus->devfreq = devm_devfreq_add_device(dev, profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) DEVFREQ_GOV_SIMPLE_ONDEMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ondemand_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (IS_ERR(bus->devfreq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) dev_err(dev, "failed to add devfreq device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return PTR_ERR(bus->devfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* Register opp_notifier to catch the change of OPP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ret = devm_devfreq_register_opp_notifier(dev, bus->devfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) dev_err(dev, "failed to register opp notifier\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * Enable devfreq-event to get raw data which is used to determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * current bus load.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ret = exynos_bus_enable_edev(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) dev_err(dev, "failed to enable devfreq-event devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ret = exynos_bus_set_event(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) dev_err(dev, "failed to set event to devfreq-event devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) goto err_edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) err_edev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (exynos_bus_disable_edev(bus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) dev_warn(dev, "failed to disable the devfreq-event devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static int exynos_bus_profile_init_passive(struct exynos_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct devfreq_dev_profile *profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct device *dev = bus->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct devfreq_passive_data *passive_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct devfreq *parent_devfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* Initialize the struct profile and governor data for passive device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) profile->target = exynos_bus_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) profile->exit = exynos_bus_passive_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* Get the instance of parent devfreq device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) parent_devfreq = devfreq_get_devfreq_by_phandle(dev, "devfreq", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (IS_ERR(parent_devfreq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) passive_data = devm_kzalloc(dev, sizeof(*passive_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (!passive_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) passive_data->parent = parent_devfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* Add devfreq device for exynos bus with passive governor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) bus->devfreq = devm_devfreq_add_device(dev, profile, DEVFREQ_GOV_PASSIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) passive_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (IS_ERR(bus->devfreq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) "failed to add devfreq dev with passive governor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return PTR_ERR(bus->devfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static int exynos_bus_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct device_node *np = dev->of_node, *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct devfreq_dev_profile *profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct exynos_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) int ret, max_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) unsigned long min_freq, max_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) bool passive = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) dev_err(dev, "failed to find devicetree node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (!bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) mutex_init(&bus->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) bus->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) platform_set_drvdata(pdev, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) profile = devm_kzalloc(dev, sizeof(*profile), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (!profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) node = of_parse_phandle(dev->of_node, "devfreq", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) passive = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ret = exynos_bus_parent_parse_of(np, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Parse the device-tree to get the resource information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ret = exynos_bus_parse_of(np, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) goto err_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (passive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret = exynos_bus_profile_init_passive(bus, profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = exynos_bus_profile_init(bus, profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) max_state = bus->devfreq->profile->max_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) min_freq = (bus->devfreq->profile->freq_table[0] / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) max_freq = (bus->devfreq->profile->freq_table[max_state - 1] / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) pr_info("exynos-bus: new bus device registered: %s (%6ld KHz ~ %6ld KHz)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) dev_name(dev), min_freq, max_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) dev_pm_opp_of_remove_table(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) clk_disable_unprepare(bus->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) err_reg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (!passive) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dev_pm_opp_put_regulators(bus->opp_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) bus->opp_table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static void exynos_bus_shutdown(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct exynos_bus *bus = dev_get_drvdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) devfreq_suspend_device(bus->devfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static int exynos_bus_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct exynos_bus *bus = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = exynos_bus_enable_edev(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) dev_err(dev, "failed to enable the devfreq-event devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static int exynos_bus_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct exynos_bus *bus = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ret = exynos_bus_disable_edev(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dev_err(dev, "failed to disable the devfreq-event devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static const struct dev_pm_ops exynos_bus_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) SET_SYSTEM_SLEEP_PM_OPS(exynos_bus_suspend, exynos_bus_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static const struct of_device_id exynos_bus_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) { .compatible = "samsung,exynos-bus", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) MODULE_DEVICE_TABLE(of, exynos_bus_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static struct platform_driver exynos_bus_platdrv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .probe = exynos_bus_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .shutdown = exynos_bus_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .name = "exynos-bus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .pm = &exynos_bus_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .of_match_table = of_match_ptr(exynos_bus_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) module_platform_driver(exynos_bus_platdrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) MODULE_DESCRIPTION("Generic Exynos Bus frequency driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) MODULE_LICENSE("GPL v2");