From 34e31390a3b939db2e0cbfef4c40d95052572df0 Mon Sep 17 00:00:00 2001 From: Jakob Berg Jespersen Date: Sat, 29 Aug 2026 10:29:09 +0200 Subject: platform/x86: int3472: support the POWER1 GPIO type INT3472 can describe a second sensor power rail as a GPIO of type POWER1 (0x08), which the driver does not recognise, so the rail is left unmapped and never enabled: int3472-discrete INT3472:01: GPIO type 0x08 unknown; the sensor may not work On the Microsoft Surface Pro 7+ the rear camera's INT3472 (INT347A, ov8865) has such a pin; without it the ov8865 "dvdd" supply resolves to a dummy regulator and the sensor never probes. Define the POWER0 (0x07) and POWER1 (0x08) GPIO types and map POWER1 to a regulator with con_id "dvdd" for all devices, the supply the in-tree ov8865 driver already requests. POWER0 is defined but left unmapped, as no device that uses it is known. With this change the Surface Pro 7+ rear camera probes and streams reliably. Link: https://github.com/linux-surface/linux-surface/pull/1867 Link: https://github.com/linux-surface/linux-surface/pull/2201 Suggested-by: Sakari Ailus Signed-off-by: Jakob Berg Jespersen Reviewed-by: Hans de Goede [Sakari Ailus: Sanitised the commit message a little.] Signed-off-by: Sakari Ailus --- include/linux/platform_data/x86/int3472.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/platform_data/x86/int3472.h b/include/linux/platform_data/x86/int3472.h index a73841dfae27..b1040e36deb8 100644 --- a/include/linux/platform_data/x86/int3472.h +++ b/include/linux/platform_data/x86/int3472.h @@ -25,6 +25,8 @@ #define INT3472_GPIO_TYPE_RESET 0x00 #define INT3472_GPIO_TYPE_POWERDOWN 0x01 #define INT3472_GPIO_TYPE_STROBE 0x02 +#define INT3472_GPIO_TYPE_POWER0 0x07 +#define INT3472_GPIO_TYPE_POWER1 0x08 #define INT3472_GPIO_TYPE_POWER_ENABLE 0x0b #define INT3472_GPIO_TYPE_CLK_ENABLE 0x0c #define INT3472_GPIO_TYPE_PRIVACY_LED 0x0d -- cgit v1.2.3 From 3b696f0d04fa42e58d2eacffd1365a56ac862db4 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Thu, 25 Jun 2026 10:17:21 -0400 Subject: device property: Introduce fwnode_graph_for_each_endpoint_scoped() Similar to recently propose for_each_child_of_node_scoped() this new version of the loop macro instantiates a new local struct fwnode_handle * that uses the __free(fwnode_handle) auto cleanup handling so that if a reference to a node is held on early exit from the loop the reference will be released. If the loop runs to completion, the child pointer will be NULL and no action will be taken. The reason this is useful is that it removes the need for fwnode_handle_put() on early loop exits. If there is a need to retain the reference, then return_ptr(child) or no_free_ptr(child) may be used to safely disable the auto cleanup. Reviewed-by: Andy Shevchenko Reviewed-by: Guoniu Zhou Reviewed-by: Laurent Pinchart Signed-off-by: Frank Li Acked-by: Danilo Krummrich Signed-off-by: Sakari Ailus --- include/linux/property.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/property.h b/include/linux/property.h index 907c790a3f01..9143fe4f5c05 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -547,6 +547,11 @@ unsigned int fwnode_graph_get_endpoint_count(const struct fwnode_handle *fwnode, for (child = fwnode_graph_get_next_endpoint(fwnode, NULL); child; \ child = fwnode_graph_get_next_endpoint(fwnode, child)) +#define fwnode_graph_for_each_endpoint_scoped(fwnode, child) \ + for (struct fwnode_handle *child __free(fwnode_handle) = \ + fwnode_graph_get_next_endpoint(fwnode, NULL); \ + child; child = fwnode_graph_get_next_endpoint(fwnode, child)) + int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, struct fwnode_endpoint *endpoint); -- cgit v1.2.3 From 1b7ef606894ac81b5d95b51fe05475a3aedba411 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 18 Sep 2026 14:56:37 +0100 Subject: phy: core: Add phy_get_by_of_node() Add new function phy_get_by_of_node() allowing lookup of a phy by device_node. Separates existing logic in _of_phy_get() into an internal helper method _of_phy_get_with_args() to allow for reuse in new method. Signed-off-by: Bryan O'Donoghue Reviewed-by: Manivannan Sadhasivam Reviewed-by: Neil Armstrong Link: https://patch.msgid.link/20260918-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v20-2-dc244e124e71@linaro.org Signed-off-by: Vinod Koul --- drivers/phy/phy-core.c | 83 ++++++++++++++++++++++++++++++++++++++----------- include/linux/phy/phy.h | 6 ++++ 2 files changed, 71 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 89addd732bff..42c27a2b4515 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -606,6 +606,38 @@ int phy_validate(struct phy *phy, enum phy_mode mode, int submode, } EXPORT_SYMBOL_GPL(phy_validate); +/** + * _of_phy_get_with_args() - lookup and obtain a reference to a phy by of_phandle_args + * @args: of_phandle_args to the phy + * + * Returns: the phy from the provider's of_xlate, -ENODEV if disabled, + * -EPROBE_DEFER if the provider is not yet registered. + */ +static struct phy *_of_phy_get_with_args(struct of_phandle_args *args) +{ + struct phy *phy; + struct phy_provider *phy_provider; + + lockdep_assert_held(&phy_provider_mutex); + + phy_provider = of_phy_provider_lookup(args->np); + if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) + return ERR_PTR(-EPROBE_DEFER); + + if (!of_device_is_available(args->np)) { + dev_warn(phy_provider->dev, "Requested PHY is disabled\n"); + phy = ERR_PTR(-ENODEV); + goto out_put_module; + } + + phy = phy_provider->of_xlate(phy_provider->dev, args); + +out_put_module: + module_put(phy_provider->owner); + + return phy; +} + /** * _of_phy_get() - lookup and obtain a reference to a phy by phandle * @np: device_node for which to get the phy @@ -620,8 +652,7 @@ EXPORT_SYMBOL_GPL(phy_validate); static struct phy *_of_phy_get(struct device_node *np, int index) { int ret; - struct phy_provider *phy_provider; - struct phy *phy = NULL; + struct phy *phy; struct of_phandle_args args; lockdep_assert_held(&phy_provider_mutex); @@ -637,22 +668,7 @@ static struct phy *_of_phy_get(struct device_node *np, int index) goto out_put_node; } - phy_provider = of_phy_provider_lookup(args.np); - if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) { - phy = ERR_PTR(-EPROBE_DEFER); - goto out_put_node; - } - - if (!of_device_is_available(args.np)) { - dev_warn(phy_provider->dev, "Requested PHY is disabled\n"); - phy = ERR_PTR(-ENODEV); - goto out_put_module; - } - - phy = phy_provider->of_xlate(phy_provider->dev, &args); - -out_put_module: - module_put(phy_provider->owner); + phy = _of_phy_get_with_args(&args); out_put_node: of_node_put(args.np); @@ -1001,6 +1017,37 @@ out_unlock: } EXPORT_SYMBOL_GPL(devm_of_phy_get_by_index); +/** + * phy_get_by_of_node() - lookup and obtain a reference to a phy by device_node + * @np: node containing the phy + * + * Returns: the phy associated with the device node or ERR_PTR. + */ +struct phy *phy_get_by_of_node(struct device_node *np) +{ + struct of_phandle_args args = { .np = np, .args_count = 0 }; + struct phy *phy; + + mutex_lock(&phy_provider_mutex); + + phy = _of_phy_get_with_args(&args); + if (IS_ERR(phy)) + goto out_unlock; + + if (!try_module_get(phy->ops->owner)) { + phy = ERR_PTR(-EPROBE_DEFER); + goto out_unlock; + } + + get_device(&phy->dev); + +out_unlock: + mutex_unlock(&phy_provider_mutex); + + return phy; +} +EXPORT_SYMBOL_GPL(phy_get_by_of_node); + /** * phy_create() - create a new phy * @dev: device that is creating the new phy diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index ea47975e288a..71c2e1639713 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -284,6 +284,7 @@ struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np, const char *con_id); struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, int index); +struct phy *phy_get_by_of_node(struct device_node *np); void of_phy_put(struct phy *phy); void phy_put(struct device *dev, struct phy *phy); void devm_phy_put(struct device *dev, struct phy *phy); @@ -493,6 +494,11 @@ static inline struct phy *devm_of_phy_get_by_index(struct device *dev, return ERR_PTR(-ENOSYS); } +static inline struct phy *phy_get_by_of_node(struct device_node *np) +{ + return ERR_PTR(-ENOSYS); +} + static inline void of_phy_put(struct phy *phy) { } -- cgit v1.2.3 From 7574a5187ba8aa72fc4b018574a721c63c55413a Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 18 Sep 2026 14:56:38 +0100 Subject: phy: core: Add devm_phy_get_by_of_node() Add a devm variant of phy_get_by_of_node() to allow for the familiar pattern of having devres automatically release resources on the driver's exit path. Reviewed-by: Manivannan Sadhasivam Signed-off-by: Bryan O'Donoghue Reviewed-by: Neil Armstrong Link: https://patch.msgid.link/20260918-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v20-3-dc244e124e71@linaro.org Signed-off-by: Vinod Koul --- drivers/phy/phy-core.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/phy/phy.h | 7 +++++++ 2 files changed, 41 insertions(+) (limited to 'include/linux') diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 42c27a2b4515..f0d2b50d1c76 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -1048,6 +1048,40 @@ out_unlock: } EXPORT_SYMBOL_GPL(phy_get_by_of_node); +/** + * devm_phy_get_by_of_node() - devm managed lookup and obtain phy reference by device node + * @dev: device requesting the PHY + * @np: device_node of the PHY provider + * + * Returns: phy associated with the device_node or ERR_PTR. devres manages + * releasing resources. + */ +struct phy *devm_phy_get_by_of_node(struct device *dev, struct device_node *np) +{ + struct phy **ptr, *phy; + struct device_link *link; + + ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + phy = phy_get_by_of_node(np); + if (IS_ERR(phy)) { + devres_free(ptr); + return phy; + } + + *ptr = phy; + devres_add(dev, ptr); + link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); + if (!link) + dev_dbg(dev, "failed to create device link to %s\n", + dev_name(phy->dev.parent)); + + return phy; +} +EXPORT_SYMBOL_GPL(devm_phy_get_by_of_node); + /** * phy_create() - create a new phy * @dev: device that is creating the new phy diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 71c2e1639713..14b924a88411 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -285,6 +285,7 @@ struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np, struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, int index); struct phy *phy_get_by_of_node(struct device_node *np); +struct phy *devm_phy_get_by_of_node(struct device *dev, struct device_node *np); void of_phy_put(struct phy *phy); void phy_put(struct device *dev, struct phy *phy); void devm_phy_put(struct device *dev, struct phy *phy); @@ -499,6 +500,12 @@ static inline struct phy *phy_get_by_of_node(struct device_node *np) return ERR_PTR(-ENOSYS); } +static inline struct phy *devm_phy_get_by_of_node(struct device *dev, + struct device_node *np) +{ + return ERR_PTR(-ENOSYS); +} + static inline void of_phy_put(struct phy *phy) { } -- cgit v1.2.3 From aeb80fb58d6a421047f896da8b316ee81a422fe3 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Oct 2026 11:43:43 +0200 Subject: media: Consolidate AtomISP v2 PCI IDs in the pci_ids.h We have a few drivers using same pair of the PCI IDs across the kernel and there seems more to go, consolidate AtomISP v2 PCI IDs in pci_ids.h database. Signed-off-by: Andy Shevchenko Reviewed-by: Hans de Goede Reviewed-by: Sakari Ailus Acked-by: Jani Nikula Acked-by: Bjorn Helgaas # pci_ids.h Signed-off-by: Sakari Ailus --- drivers/gpu/drm/i915/display/intel_display_power.c | 6 +++--- drivers/platform/x86/intel/atomisp2/pm.c | 6 +++--- drivers/staging/media/atomisp/pci/atomisp_internal.h | 2 -- drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 10 +++++----- include/linux/pci_ids.h | 2 ++ 5 files changed, 13 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 0ebec6e0c240..325d38d61a8c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -2076,9 +2076,9 @@ static void assert_ved_power_gated(struct intel_display *display) static void assert_isp_power_gated(struct intel_display *display) { static const struct pci_device_id isp_ids[] = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0f38)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x22b8)}, - {} + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISP_BYT) }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISP_BSW) }, + { } }; drm_WARN(display->drm, !pci_dev_present(isp_ids) && diff --git a/drivers/platform/x86/intel/atomisp2/pm.c b/drivers/platform/x86/intel/atomisp2/pm.c index ad1f99140962..f3dee0e58f62 100644 --- a/drivers/platform/x86/intel/atomisp2/pm.c +++ b/drivers/platform/x86/intel/atomisp2/pm.c @@ -121,9 +121,9 @@ static UNIVERSAL_DEV_PM_OPS(isp_pm_ops, isp_pci_suspend, isp_pci_resume, NULL); static const struct pci_device_id isp_id_table[] = { - { PCI_VDEVICE(INTEL, 0x0f38), }, - { PCI_VDEVICE(INTEL, 0x22b8), }, - { 0, } + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISP_BYT) }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISP_BSW) }, + { } }; MODULE_DEVICE_TABLE(pci, isp_id_table); diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h index 5a69580b8251..1a05fc331557 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h @@ -37,7 +37,6 @@ (((isp)->media_dev.hw_revision & ATOMISP_HW_REVISION_MASK) == \ ((rev) << ATOMISP_HW_REVISION_SHIFT)) -#define ATOMISP_PCI_DEVICE_SOC_BYT 0x0f38 /* MRFLD with 0x1178: ISP freq can burst to 457MHz */ #define ATOMISP_PCI_DEVICE_SOC_MRFLD 0x1178 /* MRFLD with 0x1179: max ISP freq limited to 400MHz */ @@ -45,7 +44,6 @@ /* MRFLD with 0x117a: max ISP freq is 400MHz and max freq at Vmin is 200MHz */ #define ATOMISP_PCI_DEVICE_SOC_MRFLD_117A 0x117a #define ATOMISP_PCI_DEVICE_SOC_ANN 0x1478 -#define ATOMISP_PCI_DEVICE_SOC_CHT 0x22b8 #define ATOMISP_PCI_REV_MRFLD_A0_MAX 0 #define ATOMISP_PCI_REV_BYT_A0_MAX 4 diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 476fe143a591..ab8727a806bf 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1239,7 +1239,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i } isp->hpll_freq = HPLL_FREQ_1600MHZ; break; - case ATOMISP_PCI_DEVICE_SOC_BYT: + case PCI_DEVICE_ID_INTEL_ISP_BYT: isp->media_dev.hw_revision = (ATOMISP_HW_REVISION_ISP2400 << ATOMISP_HW_REVISION_SHIFT) | @@ -1284,7 +1284,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i isp->dfs = &dfs_config_merr; isp->hpll_freq = HPLL_FREQ_1600MHZ; break; - case ATOMISP_PCI_DEVICE_SOC_CHT: + case PCI_DEVICE_ID_INTEL_ISP_BSW: isp->media_dev.hw_revision = (ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT); isp->media_dev.hw_revision |= pdev->revision < 2 ? @@ -1487,12 +1487,12 @@ static const struct pci_device_id atomisp_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ATOMISP_PCI_DEVICE_SOC_MRFLD_1179)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ATOMISP_PCI_DEVICE_SOC_MRFLD_117A)}, /* Baytrail */ - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ATOMISP_PCI_DEVICE_SOC_BYT)}, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ISP_BYT) }, /* Anniedale (Merrifield+ / Moorefield) */ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ATOMISP_PCI_DEVICE_SOC_ANN)}, /* Cherrytrail */ - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ATOMISP_PCI_DEVICE_SOC_CHT)}, - {0,} + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ISP_BSW) }, + { } }; MODULE_DEVICE_TABLE(pci, atomisp_pci_tbl); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 63774ae2bf71..0693e4532a68 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2732,6 +2732,7 @@ #define PCI_DEVICE_ID_INTEL_HDA_HSW_3 0x0d0c #define PCI_DEVICE_ID_INTEL_HDA_BYT 0x0f04 #define PCI_DEVICE_ID_INTEL_SST_BYT 0x0f28 +#define PCI_DEVICE_ID_INTEL_ISP_BYT 0x0f38 #define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062 #define PCI_DEVICE_ID_INTEL_82573E_SOL 0x1085 #define PCI_DEVICE_ID_INTEL_82573L_SOL 0x108f @@ -2787,6 +2788,7 @@ #define PCI_DEVICE_ID_INTEL_VMD_201D 0x201d #define PCI_DEVICE_ID_INTEL_HDA_BSW 0x2284 #define PCI_DEVICE_ID_INTEL_SST_BSW 0x22a8 +#define PCI_DEVICE_ID_INTEL_ISP_BSW 0x22b8 #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310 #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX 0x231f #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 -- cgit v1.2.3