Skip to content

Commit 77d1c1c

Browse files
committed
Merge branch 'refs/heads/bits/030-misc' into asahi-wip
2 parents 64f5dc4 + 8bad6a3 commit 77d1c1c

25 files changed

Lines changed: 384 additions & 83 deletions

File tree

drivers/base/core.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,33 @@ void fw_devlink_purge_absent_suppliers(struct fwnode_handle *fwnode)
202202
}
203203
EXPORT_SYMBOL_GPL(fw_devlink_purge_absent_suppliers);
204204

205+
/**
206+
* fw_devlink_count_absent_consumers - Return how many consumers have
207+
* either not been created yet, or do not yet have a driver attached.
208+
* @fwnode: fwnode of the supplier
209+
*/
210+
int fw_devlink_count_absent_consumers(struct fwnode_handle *fwnode)
211+
{
212+
struct fwnode_link *link, *tmp;
213+
struct device_link *dlink, *dtmp;
214+
struct device *sup_dev = get_dev_from_fwnode(fwnode);
215+
int count = 0;
216+
217+
list_for_each_entry_safe(link, tmp, &fwnode->consumers, s_hook)
218+
count++;
219+
220+
if (!sup_dev)
221+
return count;
222+
223+
list_for_each_entry_safe(dlink, dtmp, &sup_dev->links.consumers, s_node)
224+
if (dlink->consumer->links.status != DL_DEV_DRIVER_BOUND)
225+
count++;
226+
227+
return count;
228+
}
229+
EXPORT_SYMBOL_GPL(fw_devlink_count_absent_consumers);
230+
231+
205232
/**
206233
* __fwnode_links_move_consumers - Move consumer from @from to @to fwnode_handle
207234
* @from: move consumers away from this fwnode

drivers/base/firmware_loader/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,8 @@ static int fw_decompress_xz(struct device *dev, struct fw_priv *fw_priv,
470470
static char fw_path_para[256];
471471
static const char * const fw_path[] = {
472472
fw_path_para,
473+
"/lib/firmware/vendor/" UTS_RELEASE,
474+
"/lib/firmware/vendor",
473475
"/lib/firmware/updates/" UTS_RELEASE,
474476
"/lib/firmware/updates",
475477
"/lib/firmware/" UTS_RELEASE,

drivers/base/power/domain.c

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define pr_fmt(fmt) "PM: " fmt
88

99
#include <linux/delay.h>
10+
#include <linux/fwnode.h>
1011
#include <linux/kernel.h>
1112
#include <linux/io.h>
1213
#include <linux/platform_device.h>
@@ -130,6 +131,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
130131
#define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
131132
#define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
132133
#define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
134+
#define genpd_is_defer_off(genpd) (genpd->flags & GENPD_FLAG_DEFER_OFF)
133135

134136
static inline bool irq_safe_dev_in_sleep_domain(struct device *dev,
135137
const struct generic_pm_domain *genpd)
@@ -654,6 +656,27 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
654656
queue_work(pm_wq, &genpd->power_off_work);
655657
}
656658

659+
/**
660+
* genpd_must_defer - Check whether the genpd cannot be safely powered off.
661+
* @genpd: PM domain about to be powered down.
662+
* @one_dev_probing: True if we are being called from RPM callbacks on a device that
663+
* is probing, to allow poweroff if that device is the sole remaining consumer probing.
664+
*
665+
* Returns true if the @genpd has the GENPD_FLAG_DEFER_OFF flag and there
666+
* are any consumer devices which either do not exist yet (only represented
667+
* by fwlinks) or whose drivers have not probed yet.
668+
*/
669+
static bool genpd_must_defer(struct generic_pm_domain *genpd, bool one_dev_probing)
670+
{
671+
if (genpd_is_defer_off(genpd) && genpd->has_provider) {
672+
int absent = fw_devlink_count_absent_consumers(genpd->provider);
673+
674+
if (absent > (one_dev_probing ? 1 : 0))
675+
return true;
676+
}
677+
return false;
678+
}
679+
657680
/**
658681
* genpd_power_off - Remove power from a given PM domain.
659682
* @genpd: PM domain to power down.
@@ -667,7 +690,7 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
667690
* have been powered down, remove power from @genpd.
668691
*/
669692
static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
670-
unsigned int depth)
693+
bool one_dev_probing, unsigned int depth)
671694
{
672695
struct pm_domain_data *pdd;
673696
struct gpd_link *link;
@@ -717,6 +740,14 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
717740
if (not_suspended > 1 || (not_suspended == 1 && !one_dev_on))
718741
return -EBUSY;
719742

743+
/*
744+
* Do not allow PM domain to be powered off if it is marked
745+
* as GENPD_FLAG_DEFER_OFF and there are consumer devices
746+
* which have not probed yet.
747+
*/
748+
if (genpd_must_defer(genpd, one_dev_probing))
749+
return -EBUSY;
750+
720751
if (genpd->gov && genpd->gov->power_down_ok) {
721752
if (!genpd->gov->power_down_ok(&genpd->domain))
722753
return -EAGAIN;
@@ -743,7 +774,7 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
743774
list_for_each_entry(link, &genpd->child_links, child_node) {
744775
genpd_sd_counter_dec(link->parent);
745776
genpd_lock_nested(link->parent, depth + 1);
746-
genpd_power_off(link->parent, false, depth + 1);
777+
genpd_power_off(link->parent, false, false, depth + 1);
747778
genpd_unlock(link->parent);
748779
}
749780

@@ -801,7 +832,7 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth)
801832
child_node) {
802833
genpd_sd_counter_dec(link->parent);
803834
genpd_lock_nested(link->parent, depth + 1);
804-
genpd_power_off(link->parent, false, depth + 1);
835+
genpd_power_off(link->parent, false, false, depth + 1);
805836
genpd_unlock(link->parent);
806837
}
807838

@@ -868,7 +899,7 @@ static void genpd_power_off_work_fn(struct work_struct *work)
868899
genpd = container_of(work, struct generic_pm_domain, power_off_work);
869900

870901
genpd_lock(genpd);
871-
genpd_power_off(genpd, false, 0);
902+
genpd_power_off(genpd, false, false, 0);
872903
genpd_unlock(genpd);
873904
}
874905

@@ -933,6 +964,7 @@ static int genpd_runtime_suspend(struct device *dev)
933964
struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);
934965
struct gpd_timing_data *td = gpd_data->td;
935966
bool runtime_pm = pm_runtime_enabled(dev);
967+
bool probing = dev->links.status != DL_DEV_DRIVER_BOUND;
936968
ktime_t time_start = 0;
937969
s64 elapsed_ns;
938970
int ret;
@@ -987,7 +1019,7 @@ static int genpd_runtime_suspend(struct device *dev)
9871019
return 0;
9881020

9891021
genpd_lock(genpd);
990-
genpd_power_off(genpd, true, 0);
1022+
genpd_power_off(genpd, true, probing, 0);
9911023
gpd_data->rpm_pstate = genpd_drop_performance_state(dev);
9921024
genpd_unlock(genpd);
9931025

@@ -1008,6 +1040,7 @@ static int genpd_runtime_resume(struct device *dev)
10081040
struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);
10091041
struct gpd_timing_data *td = gpd_data->td;
10101042
bool timed = td && pm_runtime_enabled(dev);
1043+
bool probing = dev->links.status != DL_DEV_DRIVER_BOUND;
10111044
ktime_t time_start = 0;
10121045
s64 elapsed_ns;
10131046
int ret;
@@ -1065,7 +1098,7 @@ static int genpd_runtime_resume(struct device *dev)
10651098
err_poweroff:
10661099
if (!pm_runtime_is_irq_safe(dev) || genpd_is_irq_safe(genpd)) {
10671100
genpd_lock(genpd);
1068-
genpd_power_off(genpd, true, 0);
1101+
genpd_power_off(genpd, true, probing, 0);
10691102
gpd_data->rpm_pstate = genpd_drop_performance_state(dev);
10701103
genpd_unlock(genpd);
10711104
}
@@ -1131,6 +1164,9 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
11311164
|| atomic_read(&genpd->sd_count) > 0)
11321165
return;
11331166

1167+
if (genpd_must_defer(genpd, false))
1168+
return;
1169+
11341170
/* Check that the children are in their deepest (powered-off) state. */
11351171
list_for_each_entry(link, &genpd->parent_links, parent_node) {
11361172
struct generic_pm_domain *child = link->child;
@@ -2096,6 +2132,12 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
20962132
return -EINVAL;
20972133
}
20982134

2135+
/* Deferred-off power domains should be powered on at initialization. */
2136+
if (genpd_is_defer_off(genpd) && !genpd_status_on(genpd)) {
2137+
pr_warn("deferred-off PM domain %s is not on at init\n", genpd->name);
2138+
genpd->flags &= ~GENPD_FLAG_DEFER_OFF;
2139+
}
2140+
20992141
/* Multiple states but no governor doesn't make sense. */
21002142
if (!gov && genpd->state_count > 1)
21012143
pr_warn("%s: no governor for states\n", genpd->name);

drivers/gpu/drm/tiny/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ config DRM_SIMPLEDRM
8585
select APERTURE_HELPERS
8686
select DRM_GEM_SHMEM_HELPER
8787
select DRM_KMS_HELPER
88+
select BACKLIGHT_CLASS_DEVICE
8889
help
8990
DRM driver for simple platform-provided framebuffers.
9091

@@ -96,6 +97,13 @@ config DRM_SIMPLEDRM
9697
On x86 BIOS or UEFI systems, you should also select SYSFB_SIMPLEFB
9798
to use UEFI and VESA framebuffers.
9899

100+
config DRM_SIMPLEDRM_BACKLIGHT
101+
bool "Backlight support for simpledrm"
102+
depends on DRM_SIMPLEDRM && !DRM_APPLE
103+
select BACKLIGHT_CLASS_DEVICE
104+
help
105+
Enable backlight support for simpledrm.
106+
99107
config TINYDRM_HX8357D
100108
tristate "DRM support for HX8357D display panels"
101109
depends on DRM && SPI

drivers/gpu/drm/tiny/simpledrm.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22

3+
#if defined CONFIG_DRM_SIMPLEDRM_BACKLIGHT
4+
#include <linux/backlight.h>
5+
#endif
36
#include <linux/clk.h>
47
#include <linux/of_clk.h>
58
#include <linux/minmax.h>
@@ -243,6 +246,10 @@ struct simpledrm_device {
243246
struct drm_crtc crtc;
244247
struct drm_encoder encoder;
245248
struct drm_connector connector;
249+
#if defined CONFIG_DRM_SIMPLEDRM_BACKLIGHT
250+
/* backlight */
251+
struct backlight_device *backlight;
252+
#endif
246253
};
247254

248255
static struct simpledrm_device *simpledrm_device_of_dev(struct drm_device *dev)
@@ -553,6 +560,28 @@ static enum drm_mode_status simpledrm_crtc_helper_mode_valid(struct drm_crtc *cr
553560
return drm_crtc_helper_mode_valid_fixed(crtc, mode, &sdev->mode);
554561
}
555562

563+
#if defined CONFIG_DRM_SIMPLEDRM_BACKLIGHT
564+
static void simpledrm_crtc_helper_atomic_enable(struct drm_crtc *crtc,
565+
struct drm_atomic_state *state)
566+
{
567+
struct drm_device *dev = crtc->dev;
568+
struct simpledrm_device *sdev = simpledrm_device_of_dev(dev);
569+
570+
if (sdev->backlight)
571+
backlight_enable(sdev->backlight);
572+
}
573+
574+
static void simpledrm_crtc_helper_atomic_disable(struct drm_crtc *crtc,
575+
struct drm_atomic_state *state)
576+
{
577+
struct drm_device *dev = crtc->dev;
578+
struct simpledrm_device *sdev = simpledrm_device_of_dev(dev);
579+
580+
if (sdev->backlight)
581+
backlight_disable(sdev->backlight);
582+
}
583+
#endif
584+
556585
/*
557586
* The CRTC is always enabled. Screen updates are performed by
558587
* the primary plane's atomic_update function. Disabling clears
@@ -561,6 +590,10 @@ static enum drm_mode_status simpledrm_crtc_helper_mode_valid(struct drm_crtc *cr
561590
static const struct drm_crtc_helper_funcs simpledrm_crtc_helper_funcs = {
562591
.mode_valid = simpledrm_crtc_helper_mode_valid,
563592
.atomic_check = drm_crtc_helper_atomic_check,
593+
#if defined CONFIG_DRM_SIMPLEDRM_BACKLIGHT
594+
.atomic_enable = simpledrm_crtc_helper_atomic_enable,
595+
.atomic_disable = simpledrm_crtc_helper_atomic_disable,
596+
#endif
564597
};
565598

566599
static const struct drm_crtc_funcs simpledrm_crtc_funcs = {
@@ -649,6 +682,11 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
649682
* Hardware settings
650683
*/
651684

685+
#if defined CONFIG_DRM_SIMPLEDRM_BACKLIGHT
686+
sdev->backlight = devm_of_find_backlight(&pdev->dev);
687+
if (IS_ERR(sdev->backlight))
688+
sdev->backlight = NULL;
689+
#endif
652690
ret = simpledrm_device_init_clocks(sdev);
653691
if (ret)
654692
return ERR_PTR(ret);

0 commit comments

Comments
 (0)