diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-08 06:23:40 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-08 06:23:40 +0200 |
commit | 6afd563d4bbc1924b7de9e053324c007e0d36476 (patch) | |
tree | 619c2270f6f09ce8c9eb7f6aa448f07f67ffa8e8 /drivers/soc | |
parent | Merge tag 'armsoc-arm64' of git://git.kernel.org/pub/scm/linux/kernel/git/arm... (diff) | |
parent | bus: qcom-ebi2: depend on HAS_IOMEM (diff) | |
download | linux-6afd563d4bbc1924b7de9e053324c007e0d36476.tar.xz linux-6afd563d4bbc1924b7de9e053324c007e0d36476.zip |
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Arnd Bergmann:
"Driver updates for ARM SoCs, including a couple of newly added
drivers:
- The Qualcomm external bus interface 2 (EBI2), used in some of their
mobile phone chips for connecting flash memory, LCD displays or
other peripherals
- Secure monitor firmware for Amlogic SoCs, and an NVMEM driver for
the EFUSE based on that firmware interface.
- Perf support for the AppliedMicro X-Gene performance monitor unit
- Reset driver for STMicroelectronics STM32
- Reset driver for SocioNext UniPhier SoCs
Aside from these, there are minor updates to SoC-specific bus,
clocksource, firmware, pinctrl, reset, rtc and pmic drivers"
* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (50 commits)
bus: qcom-ebi2: depend on HAS_IOMEM
pinctrl: mvebu: orion5x: Generalise mv88f5181l support for 88f5181
clk: mvebu: Add clk support for the orion5x SoC mv88f5181
dt-bindings: EXYNOS: Add Exynos5433 PMU compatible
clocksource: exynos_mct: Add the support for ARM64
perf: xgene: Add APM X-Gene SoC Performance Monitoring Unit driver
Documentation: Add documentation for APM X-Gene SoC PMU DTS binding
MAINTAINERS: Add entry for APM X-Gene SoC PMU driver
bus: qcom: add EBI2 driver
bus: qcom: add EBI2 device tree bindings
rtc: rtc-pm8xxx: Add support for pm8018 rtc
nvmem: amlogic: Add Amlogic Meson EFUSE driver
firmware: Amlogic: Add secure monitor driver
soc: qcom: smd: Reset rx tail rather than tx
memory: atmel-sdramc: fix a possible NULL dereference
reset: hi6220: allow to compile test driver on other architectures
reset: zynq: add driver Kconfig option
reset: sunxi: add driver Kconfig option
reset: stm32: add driver Kconfig option
reset: socfpga: add driver Kconfig option
...
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/mediatek/mtk-pmic-wrap.c | 2 | ||||
-rw-r--r-- | drivers/soc/qcom/smd.c | 265 | ||||
-rw-r--r-- | drivers/soc/qcom/smem.c | 3 | ||||
-rw-r--r-- | drivers/soc/rockchip/pm_domains.c | 100 | ||||
-rw-r--r-- | drivers/soc/tegra/pmc.c | 28 |
5 files changed, 223 insertions, 175 deletions
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index a003ba26ca6e..a5f10936fb9c 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c @@ -583,7 +583,7 @@ static int pwrap_wait_for_state(struct pmic_wrapper *wrp, { unsigned long timeout; - timeout = jiffies + usecs_to_jiffies(255); + timeout = jiffies + usecs_to_jiffies(10000); do { if (time_after(jiffies, timeout)) diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c index ac1957dfdf24..322034ab9d37 100644 --- a/drivers/soc/qcom/smd.c +++ b/drivers/soc/qcom/smd.c @@ -95,7 +95,7 @@ static const struct { /** * struct qcom_smd_edge - representing a remote processor - * @smd: handle to qcom_smd + * @dev: device for this edge * @of_node: of_node handle for information related to this edge * @edge_id: identifier of this edge * @remote_pid: identifier of remote processor @@ -111,7 +111,8 @@ static const struct { * @state_work: work item for edge state changes */ struct qcom_smd_edge { - struct qcom_smd *smd; + struct device dev; + struct device_node *of_node; unsigned edge_id; unsigned remote_pid; @@ -135,6 +136,8 @@ struct qcom_smd_edge { struct work_struct state_work; }; +#define to_smd_edge(d) container_of(d, struct qcom_smd_edge, dev) + /* * SMD channel states. */ @@ -197,20 +200,6 @@ struct qcom_smd_channel { void *drvdata; struct list_head list; - struct list_head dev_list; -}; - -/** - * struct qcom_smd - smd struct - * @dev: device struct - * @num_edges: number of entries in @edges - * @edges: array of edges to be handled - */ -struct qcom_smd { - struct device *dev; - - unsigned num_edges; - struct qcom_smd_edge edges[0]; }; /* @@ -374,7 +363,7 @@ static void qcom_smd_channel_reset(struct qcom_smd_channel *channel) SET_TX_CHANNEL_FLAG(channel, fSTATE, 1); SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 1); SET_TX_CHANNEL_INFO(channel, head, 0); - SET_TX_CHANNEL_INFO(channel, tail, 0); + SET_RX_CHANNEL_INFO(channel, tail, 0); qcom_smd_signal_channel(channel); @@ -421,7 +410,7 @@ static void qcom_smd_channel_set_state(struct qcom_smd_channel *channel, if (channel->state == state) return; - dev_dbg(edge->smd->dev, "set_state(%s, %d)\n", channel->name, state); + dev_dbg(&edge->dev, "set_state(%s, %d)\n", channel->name, state); SET_TX_CHANNEL_FLAG(channel, fDSR, is_open); SET_TX_CHANNEL_FLAG(channel, fCTS, is_open); @@ -891,8 +880,6 @@ static int qcom_smd_dev_remove(struct device *dev) struct qcom_smd_device *qsdev = to_smd_device(dev); struct qcom_smd_driver *qsdrv = to_smd_driver(dev); struct qcom_smd_channel *channel = qsdev->channel; - struct qcom_smd_channel *tmp; - struct qcom_smd_channel *ch; qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSING); @@ -911,15 +898,9 @@ static int qcom_smd_dev_remove(struct device *dev) if (qsdrv->remove) qsdrv->remove(qsdev); - /* - * The client is now gone, close and release all channels associated - * with this sdev - */ - list_for_each_entry_safe(ch, tmp, &channel->dev_list, dev_list) { - qcom_smd_channel_close(ch); - list_del(&ch->dev_list); - ch->qsdev = NULL; - } + /* The client is now gone, close the primary channel */ + qcom_smd_channel_close(channel); + channel->qsdev = NULL; return 0; } @@ -973,13 +954,12 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel) struct qcom_smd_device *qsdev; struct qcom_smd_edge *edge = channel->edge; struct device_node *node; - struct qcom_smd *smd = edge->smd; int ret; if (channel->qsdev) return -EEXIST; - dev_dbg(smd->dev, "registering '%s'\n", channel->name); + dev_dbg(&edge->dev, "registering '%s'\n", channel->name); qsdev = kzalloc(sizeof(*qsdev), GFP_KERNEL); if (!qsdev) @@ -990,7 +970,7 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel) edge->of_node->name, node ? node->name : channel->name); - qsdev->dev.parent = smd->dev; + qsdev->dev.parent = &edge->dev; qsdev->dev.bus = &qcom_smd_bus; qsdev->dev.release = qcom_smd_release_device; qsdev->dev.of_node = node; @@ -1001,7 +981,7 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel) ret = device_register(&qsdev->dev); if (ret) { - dev_err(smd->dev, "device_register failed: %d\n", ret); + dev_err(&edge->dev, "device_register failed: %d\n", ret); put_device(&qsdev->dev); } @@ -1091,6 +1071,8 @@ qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name) * * Returns a channel handle on success, or -EPROBE_DEFER if the channel isn't * ready. + * + * Any channels returned must be closed with a call to qcom_smd_close_channel() */ struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *parent, const char *name, @@ -1120,15 +1102,21 @@ struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *parent, return ERR_PTR(ret); } - /* - * Append the list of channel to the channels associated with the sdev - */ - list_add_tail(&channel->dev_list, &sdev->channel->dev_list); - return channel; } EXPORT_SYMBOL(qcom_smd_open_channel); +/** + * qcom_smd_close_channel() - close an additionally opened channel + * @channel: channel handle, returned by qcom_smd_open_channel() + */ +void qcom_smd_close_channel(struct qcom_smd_channel *channel) +{ + qcom_smd_channel_close(channel); + channel->qsdev = NULL; +} +EXPORT_SYMBOL(qcom_smd_close_channel); + /* * Allocate the qcom_smd_channel object for a newly found smd channel, * retrieving and validating the smem items involved. @@ -1139,20 +1127,18 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed char *name) { struct qcom_smd_channel *channel; - struct qcom_smd *smd = edge->smd; size_t fifo_size; size_t info_size; void *fifo_base; void *info; int ret; - channel = devm_kzalloc(smd->dev, sizeof(*channel), GFP_KERNEL); + channel = devm_kzalloc(&edge->dev, sizeof(*channel), GFP_KERNEL); if (!channel) return ERR_PTR(-ENOMEM); - INIT_LIST_HEAD(&channel->dev_list); channel->edge = edge; - channel->name = devm_kstrdup(smd->dev, name, GFP_KERNEL); + channel->name = devm_kstrdup(&edge->dev, name, GFP_KERNEL); if (!channel->name) return ERR_PTR(-ENOMEM); @@ -1175,7 +1161,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed } else if (info_size == 2 * sizeof(struct smd_channel_info)) { channel->info = info; } else { - dev_err(smd->dev, + dev_err(&edge->dev, "channel info of size %zu not supported\n", info_size); ret = -EINVAL; goto free_name_and_channel; @@ -1190,7 +1176,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed /* The channel consist of a rx and tx fifo of equal size */ fifo_size /= 2; - dev_dbg(smd->dev, "new channel '%s' info-size: %zu fifo-size: %zu\n", + dev_dbg(&edge->dev, "new channel '%s' info-size: %zu fifo-size: %zu\n", name, info_size, fifo_size); channel->tx_fifo = fifo_base; @@ -1202,8 +1188,8 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed return channel; free_name_and_channel: - devm_kfree(smd->dev, channel->name); - devm_kfree(smd->dev, channel); + devm_kfree(&edge->dev, channel->name); + devm_kfree(&edge->dev, channel); return ERR_PTR(ret); } @@ -1219,7 +1205,6 @@ static void qcom_channel_scan_worker(struct work_struct *work) struct qcom_smd_alloc_entry *alloc_tbl; struct qcom_smd_alloc_entry *entry; struct qcom_smd_channel *channel; - struct qcom_smd *smd = edge->smd; unsigned long flags; unsigned fifo_id; unsigned info_id; @@ -1263,7 +1248,7 @@ static void qcom_channel_scan_worker(struct work_struct *work) list_add(&channel->list, &edge->channels); spin_unlock_irqrestore(&edge->channels_lock, flags); - dev_dbg(smd->dev, "new channel found: '%s'\n", channel->name); + dev_dbg(&edge->dev, "new channel found: '%s'\n", channel->name); set_bit(i, edge->allocated[tbl]); wake_up_interruptible(&edge->new_channel_event); @@ -1350,22 +1335,6 @@ static int qcom_smd_parse_edge(struct device *dev, edge->of_node = of_node_get(node); - irq = irq_of_parse_and_map(node, 0); - if (irq < 0) { - dev_err(dev, "required smd interrupt missing\n"); - return -EINVAL; - } - - ret = devm_request_irq(dev, irq, - qcom_smd_edge_intr, IRQF_TRIGGER_RISING, - node->name, edge); - if (ret) { - dev_err(dev, "failed to request smd irq\n"); - return ret; - } - - edge->irq = irq; - key = "qcom,smd-edge"; ret = of_property_read_u32(node, key, &edge->edge_id); if (ret) { @@ -1400,18 +1369,121 @@ static int qcom_smd_parse_edge(struct device *dev, return -EINVAL; } + irq = irq_of_parse_and_map(node, 0); + if (irq < 0) { + dev_err(dev, "required smd interrupt missing\n"); + return -EINVAL; + } + + ret = devm_request_irq(dev, irq, + qcom_smd_edge_intr, IRQF_TRIGGER_RISING, + node->name, edge); + if (ret) { + dev_err(dev, "failed to request smd irq\n"); + return ret; + } + + edge->irq = irq; + return 0; } -static int qcom_smd_probe(struct platform_device *pdev) +/* + * Release function for an edge. + * Reset the state of each associated channel and free the edge context. + */ +static void qcom_smd_edge_release(struct device *dev) +{ + struct qcom_smd_channel *channel; + struct qcom_smd_edge *edge = to_smd_edge(dev); + + list_for_each_entry(channel, &edge->channels, list) { + SET_RX_CHANNEL_INFO(channel, state, SMD_CHANNEL_CLOSED); + SET_RX_CHANNEL_INFO(channel, head, 0); + SET_RX_CHANNEL_INFO(channel, tail, 0); + } + + kfree(edge); +} + +/** + * qcom_smd_register_edge() - register an edge based on an device_node + * @parent: parent device for the edge + * @node: device_node describing the edge + * + * Returns an edge reference, or negative ERR_PTR() on failure. + */ +struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent, + struct device_node *node) { struct qcom_smd_edge *edge; - struct device_node *node; - struct qcom_smd *smd; - size_t array_size; - int num_edges; int ret; - int i = 0; + + edge = kzalloc(sizeof(*edge), GFP_KERNEL); + if (!edge) + return ERR_PTR(-ENOMEM); + + init_waitqueue_head(&edge->new_channel_event); + + edge->dev.parent = parent; + edge->dev.release = qcom_smd_edge_release; + dev_set_name(&edge->dev, "%s:%s", dev_name(parent), node->name); + ret = device_register(&edge->dev); + if (ret) { + pr_err("failed to register smd edge\n"); + return ERR_PTR(ret); + } + + ret = qcom_smd_parse_edge(&edge->dev, node, edge); + if (ret) { + dev_err(&edge->dev, "failed to parse smd edge\n"); + goto unregister_dev; + } + + schedule_work(&edge->scan_work); + + return edge; + +unregister_dev: + put_device(&edge->dev); + return ERR_PTR(ret); +} +EXPORT_SYMBOL(qcom_smd_register_edge); + +static int qcom_smd_remove_device(struct device *dev, void *data) +{ + device_unregister(dev); + of_node_put(dev->of_node); + put_device(dev); + + return 0; +} + +/** + * qcom_smd_unregister_edge() - release an edge and its children + * @edge: edge reference acquired from qcom_smd_register_edge + */ +int qcom_smd_unregister_edge(struct qcom_smd_edge *edge) +{ + int ret; + + disable_irq(edge->irq); + cancel_work_sync(&edge->scan_work); + cancel_work_sync(&edge->state_work); + + ret = device_for_each_child(&edge->dev, NULL, qcom_smd_remove_device); + if (ret) + dev_warn(&edge->dev, "can't remove smd device: %d\n", ret); + + device_unregister(&edge->dev); + + return 0; +} +EXPORT_SYMBOL(qcom_smd_unregister_edge); + +static int qcom_smd_probe(struct platform_device *pdev) +{ + struct device_node *node; void *p; /* Wait for smem */ @@ -1419,29 +1491,17 @@ static int qcom_smd_probe(struct platform_device *pdev) if (PTR_ERR(p) == -EPROBE_DEFER) return PTR_ERR(p); - num_edges = of_get_available_child_count(pdev->dev.of_node); - array_size = sizeof(*smd) + num_edges * sizeof(struct qcom_smd_edge); - smd = devm_kzalloc(&pdev->dev, array_size, GFP_KERNEL); - if (!smd) - return -ENOMEM; - smd->dev = &pdev->dev; - - smd->num_edges = num_edges; - for_each_available_child_of_node(pdev->dev.of_node, node) { - edge = &smd->edges[i++]; - edge->smd = smd; - init_waitqueue_head(&edge->new_channel_event); - - ret = qcom_smd_parse_edge(&pdev->dev, node, edge); - if (ret) - continue; + for_each_available_child_of_node(pdev->dev.of_node, node) + qcom_smd_register_edge(&pdev->dev, node); - schedule_work(&edge->scan_work); - } + return 0; +} - platform_set_drvdata(pdev, smd); +static int qcom_smd_remove_edge(struct device *dev, void *data) +{ + struct qcom_smd_edge *edge = to_smd_edge(dev); - return 0; + return qcom_smd_unregister_edge(edge); } /* @@ -1450,28 +1510,13 @@ static int qcom_smd_probe(struct platform_device *pdev) */ static int qcom_smd_remove(struct platform_device *pdev) { - struct qcom_smd_channel *channel; - struct qcom_smd_edge *edge; - struct qcom_smd *smd = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < smd->num_edges; i++) { - edge = &smd->edges[i]; - - disable_irq(edge->irq); - cancel_work_sync(&edge->scan_work); - cancel_work_sync(&edge->state_work); - - /* No need to lock here, because the writer is gone */ - list_for_each_entry(channel, &edge->channels, list) { - if (!channel->qsdev) - continue; + int ret; - qcom_smd_destroy_device(channel); - } - } + ret = device_for_each_child(&pdev->dev, NULL, qcom_smd_remove_edge); + if (ret) + dev_warn(&pdev->dev, "can't remove smd device: %d\n", ret); - return 0; + return ret; } static const struct of_device_id qcom_smd_of_match[] = { diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 2e1aa9f130f4..18ec52f2078a 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -740,7 +740,8 @@ static int qcom_smem_probe(struct platform_device *pdev) hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0); if (hwlock_id < 0) { - dev_err(&pdev->dev, "failed to retrieve hwlock\n"); + if (hwlock_id != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to retrieve hwlock\n"); return hwlock_id; } diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 44842a205e4b..7acd1517dd37 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -27,6 +27,7 @@ struct rockchip_domain_info { int req_mask; int idle_mask; int ack_mask; + bool active_wakeup; }; struct rockchip_pmu_info { @@ -75,23 +76,24 @@ struct rockchip_pmu { #define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd) -#define DOMAIN(pwr, status, req, idle, ack) \ +#define DOMAIN(pwr, status, req, idle, ack, wakeup) \ { \ .pwr_mask = (pwr >= 0) ? BIT(pwr) : 0, \ .status_mask = (status >= 0) ? BIT(status) : 0, \ .req_mask = (req >= 0) ? BIT(req) : 0, \ .idle_mask = (idle >= 0) ? BIT(idle) : 0, \ .ack_mask = (ack >= 0) ? BIT(ack) : 0, \ + .active_wakeup = wakeup, \ } -#define DOMAIN_RK3288(pwr, status, req) \ - DOMAIN(pwr, status, req, req, (req) + 16) +#define DOMAIN_RK3288(pwr, status, req, wakeup) \ + DOMAIN(pwr, status, req, req, (req) + 16, wakeup) -#define DOMAIN_RK3368(pwr, status, req) \ - DOMAIN(pwr, status, req, (req) + 16, req) +#define DOMAIN_RK3368(pwr, status, req, wakeup) \ + DOMAIN(pwr, status, req, (req) + 16, req, wakeup) -#define DOMAIN_RK3399(pwr, status, req) \ - DOMAIN(pwr, status, req, req, req) +#define DOMAIN_RK3399(pwr, status, req, wakeup) \ + DOMAIN(pwr, status, req, req, req, wakeup) static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd) { @@ -295,6 +297,17 @@ static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd, pm_clk_destroy(dev); } +static bool rockchip_active_wakeup(struct device *dev) +{ + struct generic_pm_domain *genpd; + struct rockchip_pm_domain *pd; + + genpd = pd_to_genpd(dev->pm_domain); + pd = container_of(genpd, struct rockchip_pm_domain, genpd); + + return pd->info->active_wakeup; +} + static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, struct device_node *node) { @@ -415,6 +428,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, pd->genpd.power_on = rockchip_pd_power_on; pd->genpd.attach_dev = rockchip_pd_attach_dev; pd->genpd.detach_dev = rockchip_pd_detach_dev; + pd->genpd.dev_ops.active_wakeup = rockchip_active_wakeup; pd->genpd.flags = GENPD_FLAG_PM_CLK; pm_genpd_init(&pd->genpd, NULL, false); @@ -623,48 +637,48 @@ err_out: } static const struct rockchip_domain_info rk3288_pm_domains[] = { - [RK3288_PD_VIO] = DOMAIN_RK3288(7, 7, 4), - [RK3288_PD_HEVC] = DOMAIN_RK3288(14, 10, 9), - [RK3288_PD_VIDEO] = DOMAIN_RK3288(8, 8, 3), - [RK3288_PD_GPU] = DOMAIN_RK3288(9, 9, 2), + [RK3288_PD_VIO] = DOMAIN_RK3288(7, 7, 4, false), + [RK3288_PD_HEVC] = DOMAIN_RK3288(14, 10, 9, false), + [RK3288_PD_VIDEO] = DOMAIN_RK3288(8, 8, 3, false), + [RK3288_PD_GPU] = DOMAIN_RK3288(9, 9, 2, false), }; static const struct rockchip_domain_info rk3368_pm_domains[] = { - [RK3368_PD_PERI] = DOMAIN_RK3368(13, 12, 6), - [RK3368_PD_VIO] = DOMAIN_RK3368(15, 14, 8), - [RK3368_PD_VIDEO] = DOMAIN_RK3368(14, 13, 7), - [RK3368_PD_GPU_0] = DOMAIN_RK3368(16, 15, 2), - [RK3368_PD_GPU_1] = DOMAIN_RK3368(17, 16, 2), + [RK3368_PD_PERI] = DOMAIN_RK3368(13, 12, 6, true), + [RK3368_PD_VIO] = DOMAIN_RK3368(15, 14, 8, false), + [RK3368_PD_VIDEO] = DOMAIN_RK3368(14, 13, 7, false), + [RK3368_PD_GPU_0] = DOMAIN_RK3368(16, 15, 2, false), + [RK3368_PD_GPU_1] = DOMAIN_RK3368(17, 16, 2, false), }; static const struct rockchip_domain_info rk3399_pm_domains[] = { - [RK3399_PD_TCPD0] = DOMAIN_RK3399(8, 8, -1), - [RK3399_PD_TCPD1] = DOMAIN_RK3399(9, 9, -1), - [RK3399_PD_CCI] = DOMAIN_RK3399(10, 10, -1), - [RK3399_PD_CCI0] = DOMAIN_RK3399(-1, -1, 15), - [RK3399_PD_CCI1] = DOMAIN_RK3399(-1, -1, 16), - [RK3399_PD_PERILP] = DOMAIN_RK3399(11, 11, 1), - [RK3399_PD_PERIHP] = DOMAIN_RK3399(12, 12, 2), - [RK3399_PD_CENTER] = DOMAIN_RK3399(13, 13, 14), - [RK3399_PD_VIO] = DOMAIN_RK3399(14, 14, 17), - [RK3399_PD_GPU] = DOMAIN_RK3399(15, 15, 0), - [RK3399_PD_VCODEC] = DOMAIN_RK3399(16, 16, 3), - [RK3399_PD_VDU] = DOMAIN_RK3399(17, 17, 4), - [RK3399_PD_RGA] = DOMAIN_RK3399(18, 18, 5), - [RK3399_PD_IEP] = DOMAIN_RK3399(19, 19, 6), - [RK3399_PD_VO] = DOMAIN_RK3399(20, 20, -1), - [RK3399_PD_VOPB] = DOMAIN_RK3399(-1, -1, 7), - [RK3399_PD_VOPL] = DOMAIN_RK3399(-1, -1, 8), - [RK3399_PD_ISP0] = DOMAIN_RK3399(22, 22, 9), - [RK3399_PD_ISP1] = DOMAIN_RK3399(23, 23, 10), - [RK3399_PD_HDCP] = DOMAIN_RK3399(24, 24, 11), - [RK3399_PD_GMAC] = DOMAIN_RK3399(25, 25, 23), - [RK3399_PD_EMMC] = DOMAIN_RK3399(26, 26, 24), - [RK3399_PD_USB3] = DOMAIN_RK3399(27, 27, 12), - [RK3399_PD_EDP] = DOMAIN_RK3399(28, 28, 22), - [RK3399_PD_GIC] = DOMAIN_RK3399(29, 29, 27), - [RK3399_PD_SD] = DOMAIN_RK3399(30, 30, 28), - [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399(31, 31, 29), + [RK3399_PD_TCPD0] = DOMAIN_RK3399(8, 8, -1, false), + [RK3399_PD_TCPD1] = DOMAIN_RK3399(9, 9, -1, false), + [RK3399_PD_CCI] = DOMAIN_RK3399(10, 10, -1, true), + [RK3399_PD_CCI0] = DOMAIN_RK3399(-1, -1, 15, true), + [RK3399_PD_CCI1] = DOMAIN_RK3399(-1, -1, 16, true), + [RK3399_PD_PERILP] = DOMAIN_RK3399(11, 11, 1, true), + [RK3399_PD_PERIHP] = DOMAIN_RK3399(12, 12, 2, true), + [RK3399_PD_CENTER] = DOMAIN_RK3399(13, 13, 14, true), + [RK3399_PD_VIO] = DOMAIN_RK3399(14, 14, 17, false), + [RK3399_PD_GPU] = DOMAIN_RK3399(15, 15, 0, false), + [RK3399_PD_VCODEC] = DOMAIN_RK3399(16, 16, 3, false), + [RK3399_PD_VDU] = DOMAIN_RK3399(17, 17, 4, false), + [RK3399_PD_RGA] = DOMAIN_RK3399(18, 18, 5, false), + [RK3399_PD_IEP] = DOMAIN_RK3399(19, 19, 6, false), + [RK3399_PD_VO] = DOMAIN_RK3399(20, 20, -1, false), + [RK3399_PD_VOPB] = DOMAIN_RK3399(-1, -1, 7, false), + [RK3399_PD_VOPL] = DOMAIN_RK3399(-1, -1, 8, false), + [RK3399_PD_ISP0] = DOMAIN_RK3399(22, 22, 9, false), + [RK3399_PD_ISP1] = DOMAIN_RK3399(23, 23, 10, false), + [RK3399_PD_HDCP] = DOMAIN_RK3399(24, 24, 11, false), + [RK3399_PD_GMAC] = DOMAIN_RK3399(25, 25, 23, true), + [RK3399_PD_EMMC] = DOMAIN_RK3399(26, 26, 24, true), + [RK3399_PD_USB3] = DOMAIN_RK3399(27, 27, 12, true), + [RK3399_PD_EDP] = DOMAIN_RK3399(28, 28, 22, false), + [RK3399_PD_GIC] = DOMAIN_RK3399(29, 29, 27, true), + [RK3399_PD_SD] = DOMAIN_RK3399(30, 30, 28, true), + [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399(31, 31, 29, true), }; static const struct rockchip_pmu_info rk3288_pmu = { diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 71c834f3847e..7792ed88d80b 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -967,8 +967,8 @@ static void tegra_io_rail_unprepare(void) int tegra_io_rail_power_on(unsigned int id) { - unsigned long request, status, value; - unsigned int bit, mask; + unsigned long request, status; + unsigned int bit; int err; mutex_lock(&pmc->powergates_lock); @@ -977,15 +977,9 @@ int tegra_io_rail_power_on(unsigned int id) if (err) goto error; - mask = 1 << bit; + tegra_pmc_writel(IO_DPD_REQ_CODE_OFF | BIT(bit), request); - value = tegra_pmc_readl(request); - value |= mask; - value &= ~IO_DPD_REQ_CODE_MASK; - value |= IO_DPD_REQ_CODE_OFF; - tegra_pmc_writel(value, request); - - err = tegra_io_rail_poll(status, mask, 0, 250); + err = tegra_io_rail_poll(status, BIT(bit), 0, 250); if (err) { pr_info("tegra_io_rail_poll() failed: %d\n", err); goto error; @@ -1002,8 +996,8 @@ EXPORT_SYMBOL(tegra_io_rail_power_on); int tegra_io_rail_power_off(unsigned int id) { - unsigned long request, status, value; - unsigned int bit, mask; + unsigned long request, status; + unsigned int bit; int err; mutex_lock(&pmc->powergates_lock); @@ -1014,15 +1008,9 @@ int tegra_io_rail_power_off(unsigned int id) goto error; } - mask = 1 << bit; - - value = tegra_pmc_readl(request); - value |= mask; - value &= ~IO_DPD_REQ_CODE_MASK; - value |= IO_DPD_REQ_CODE_ON; - tegra_pmc_writel(value, request); + tegra_pmc_writel(IO_DPD_REQ_CODE_ON | BIT(bit), request); - err = tegra_io_rail_poll(status, mask, mask, 250); + err = tegra_io_rail_poll(status, BIT(bit), BIT(bit), 250); if (err) goto error; |