Skip to content

Commit 7d6f7cf

Browse files
committed
Merge tag 'reset-for-v6.13' of git://git.pengutronix.de/pza/linux into soc/drivers
Reset controller updates for v6.13 * Split the Amlogic reset-meson driver into platform and auxiliary bus drivers. Add support for the reset controller in the G12 and SM1 audio clock controllers. * Replace the list of boolean parameters to the internal reset_control_get functions with an enum reset_flags bitfield, to make the code more self-descriptive. * Add devres helpers to request pre-deasserted (and automatically re-asserting during cleanup) reset controls. This allows reducing boilerplate in drivers that deassert resets for the lifetime of a device. * Use the new auto-deasserting devres helpers in reset-uniphier-glue as an example. * Add support for the LAN966x PCI device in drivers/misc, as a dependency for the following reset-microchip-sparx5 patches. * Add support for being used on the LAN966x PCI device to the reset-microchip-sparx5 driver. Commit 86f1349 ("MAINTAINERS: Add the Microchip LAN966x PCI driver entry") introduces a trivial merge conflict with commit 7280f01 ("net: lan969x: add match data for lan969x") from the net-next tree [1]. [1] https://lore.kernel.org/all/[email protected]/ * tag 'reset-for-v6.13' of git://git.pengutronix.de/pza/linux: (21 commits) misc: lan966x_pci: Fix dtc warn 'Missing interrupt-parent' misc: lan966x_pci: Fix dtc warns 'missing or empty reg/ranges property' reset: mchp: sparx5: set the dev member of the reset controller reset: mchp: sparx5: Allow building as a module reset: mchp: sparx5: Add MCHP_LAN966X_PCI dependency reset: mchp: sparx5: Map cpu-syscon locally in case of LAN966x MAINTAINERS: Add the Microchip LAN966x PCI driver entry misc: Add support for LAN966x PCI device reset: uniphier-glue: Use devm_reset_control_bulk_get_shared_deasserted() reset: Add devres helpers to request pre-deasserted reset controls reset: replace boolean parameters with flags parameter reset: amlogic: Fix small whitespace issue reset: amlogic: add auxiliary reset driver support reset: amlogic: split the device core and platform probe reset: amlogic: move drivers to a dedicated directory reset: amlogic: add reset status support reset: amlogic: use reset number instead of register count reset: amlogic: add driver parameters reset: amlogic: make parameters unsigned reset: amlogic: use generic data matching function ... Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnd Bergmann <[email protected]>
2 parents ec72578 + cf3e10c commit 7d6f7cf

21 files changed

+1235
-292
lines changed

MAINTAINERS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15087,6 +15087,12 @@ S: Maintained
1508715087
F: Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml
1508815088
F: drivers/irqchip/irq-lan966x-oic.c
1508915089

15090+
MICROCHIP LAN966X PCI DRIVER
15091+
M: Herve Codina <[email protected]>
15092+
S: Maintained
15093+
F: drivers/misc/lan966x_pci.c
15094+
F: drivers/misc/lan966x_pci.dtso
15095+
1509015096
MICROCHIP LCDFB DRIVER
1509115097
M: Nicolas Ferre <[email protected]>
1509215098

drivers/misc/Kconfig

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,30 @@ config MARVELL_CN10K_DPI
610610
To compile this driver as a module, choose M here: the module
611611
will be called mrvl_cn10k_dpi.
612612

613+
config MCHP_LAN966X_PCI
614+
tristate "Microchip LAN966x PCIe Support"
615+
depends on PCI
616+
select OF
617+
select OF_OVERLAY
618+
select IRQ_DOMAIN
619+
help
620+
This enables the support for the LAN966x PCIe device.
621+
622+
This is used to drive the LAN966x PCIe device from the host system
623+
to which it is connected. The driver uses a device tree overlay to
624+
load other drivers to support for LAN966x internal components.
625+
626+
Even if this driver does not depend on those other drivers, in order
627+
to have a fully functional board, the following drivers are needed:
628+
- fixed-clock (COMMON_CLK)
629+
- lan966x-oic (LAN966X_OIC)
630+
- lan966x-cpu-syscon (MFD_SYSCON)
631+
- lan966x-switch-reset (RESET_MCHP_SPARX5)
632+
- lan966x-pinctrl (PINCTRL_OCELOT)
633+
- lan966x-serdes (PHY_LAN966X_SERDES)
634+
- lan966x-miim (MDIO_MSCC_MIIM)
635+
- lan966x-switch (LAN966X_SWITCH)
636+
613637
source "drivers/misc/c2port/Kconfig"
614638
source "drivers/misc/eeprom/Kconfig"
615639
source "drivers/misc/cb710/Kconfig"

drivers/misc/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,7 @@ obj-$(CONFIG_TPS6594_ESM) += tps6594-esm.o
7171
obj-$(CONFIG_TPS6594_PFSM) += tps6594-pfsm.o
7272
obj-$(CONFIG_NSM) += nsm.o
7373
obj-$(CONFIG_MARVELL_CN10K_DPI) += mrvl_cn10k_dpi.o
74+
lan966x-pci-objs := lan966x_pci.o
75+
lan966x-pci-objs += lan966x_pci.dtbo.o
76+
obj-$(CONFIG_MCHP_LAN966X_PCI) += lan966x-pci.o
7477
obj-y += keba/

drivers/misc/lan966x_pci.c

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Microchip LAN966x PCI driver
4+
*
5+
* Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries.
6+
*
7+
* Authors:
8+
* Clément Léger <[email protected]>
9+
* Hervé Codina <[email protected]>
10+
*/
11+
12+
#include <linux/device.h>
13+
#include <linux/irq.h>
14+
#include <linux/irqdomain.h>
15+
#include <linux/module.h>
16+
#include <linux/of_platform.h>
17+
#include <linux/pci.h>
18+
#include <linux/pci_ids.h>
19+
#include <linux/slab.h>
20+
21+
/* Embedded dtbo symbols created by cmd_wrap_S_dtb in scripts/Makefile.lib */
22+
extern char __dtbo_lan966x_pci_begin[];
23+
extern char __dtbo_lan966x_pci_end[];
24+
25+
struct pci_dev_intr_ctrl {
26+
struct pci_dev *pci_dev;
27+
struct irq_domain *irq_domain;
28+
int irq;
29+
};
30+
31+
static int pci_dev_irq_domain_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw)
32+
{
33+
irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_simple_irq);
34+
return 0;
35+
}
36+
37+
static const struct irq_domain_ops pci_dev_irq_domain_ops = {
38+
.map = pci_dev_irq_domain_map,
39+
.xlate = irq_domain_xlate_onecell,
40+
};
41+
42+
static irqreturn_t pci_dev_irq_handler(int irq, void *data)
43+
{
44+
struct pci_dev_intr_ctrl *intr_ctrl = data;
45+
int ret;
46+
47+
ret = generic_handle_domain_irq(intr_ctrl->irq_domain, 0);
48+
return ret ? IRQ_NONE : IRQ_HANDLED;
49+
}
50+
51+
static struct pci_dev_intr_ctrl *pci_dev_create_intr_ctrl(struct pci_dev *pdev)
52+
{
53+
struct pci_dev_intr_ctrl *intr_ctrl __free(kfree) = NULL;
54+
struct fwnode_handle *fwnode;
55+
int ret;
56+
57+
fwnode = dev_fwnode(&pdev->dev);
58+
if (!fwnode)
59+
return ERR_PTR(-ENODEV);
60+
61+
intr_ctrl = kmalloc(sizeof(*intr_ctrl), GFP_KERNEL);
62+
if (!intr_ctrl)
63+
return ERR_PTR(-ENOMEM);
64+
65+
intr_ctrl->pci_dev = pdev;
66+
67+
intr_ctrl->irq_domain = irq_domain_create_linear(fwnode, 1, &pci_dev_irq_domain_ops,
68+
intr_ctrl);
69+
if (!intr_ctrl->irq_domain) {
70+
pci_err(pdev, "Failed to create irqdomain\n");
71+
return ERR_PTR(-ENOMEM);
72+
}
73+
74+
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_INTX);
75+
if (ret < 0) {
76+
pci_err(pdev, "Unable alloc irq vector (%d)\n", ret);
77+
goto err_remove_domain;
78+
}
79+
intr_ctrl->irq = pci_irq_vector(pdev, 0);
80+
ret = request_irq(intr_ctrl->irq, pci_dev_irq_handler, IRQF_SHARED,
81+
pci_name(pdev), intr_ctrl);
82+
if (ret) {
83+
pci_err(pdev, "Unable to request irq %d (%d)\n", intr_ctrl->irq, ret);
84+
goto err_free_irq_vector;
85+
}
86+
87+
return_ptr(intr_ctrl);
88+
89+
err_free_irq_vector:
90+
pci_free_irq_vectors(pdev);
91+
err_remove_domain:
92+
irq_domain_remove(intr_ctrl->irq_domain);
93+
return ERR_PTR(ret);
94+
}
95+
96+
static void pci_dev_remove_intr_ctrl(struct pci_dev_intr_ctrl *intr_ctrl)
97+
{
98+
free_irq(intr_ctrl->irq, intr_ctrl);
99+
pci_free_irq_vectors(intr_ctrl->pci_dev);
100+
irq_dispose_mapping(irq_find_mapping(intr_ctrl->irq_domain, 0));
101+
irq_domain_remove(intr_ctrl->irq_domain);
102+
kfree(intr_ctrl);
103+
}
104+
105+
static void devm_pci_dev_remove_intr_ctrl(void *intr_ctrl)
106+
{
107+
pci_dev_remove_intr_ctrl(intr_ctrl);
108+
}
109+
110+
static int devm_pci_dev_create_intr_ctrl(struct pci_dev *pdev)
111+
{
112+
struct pci_dev_intr_ctrl *intr_ctrl;
113+
114+
intr_ctrl = pci_dev_create_intr_ctrl(pdev);
115+
if (IS_ERR(intr_ctrl))
116+
return PTR_ERR(intr_ctrl);
117+
118+
return devm_add_action_or_reset(&pdev->dev, devm_pci_dev_remove_intr_ctrl, intr_ctrl);
119+
}
120+
121+
struct lan966x_pci {
122+
struct device *dev;
123+
int ovcs_id;
124+
};
125+
126+
static int lan966x_pci_load_overlay(struct lan966x_pci *data)
127+
{
128+
u32 dtbo_size = __dtbo_lan966x_pci_end - __dtbo_lan966x_pci_begin;
129+
void *dtbo_start = __dtbo_lan966x_pci_begin;
130+
131+
return of_overlay_fdt_apply(dtbo_start, dtbo_size, &data->ovcs_id, dev_of_node(data->dev));
132+
}
133+
134+
static void lan966x_pci_unload_overlay(struct lan966x_pci *data)
135+
{
136+
of_overlay_remove(&data->ovcs_id);
137+
}
138+
139+
static int lan966x_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
140+
{
141+
struct device *dev = &pdev->dev;
142+
struct lan966x_pci *data;
143+
int ret;
144+
145+
/*
146+
* On ACPI system, fwnode can point to the ACPI node.
147+
* This driver needs an of_node to be used as the device-tree overlay
148+
* target. This of_node should be set by the PCI core if it succeeds in
149+
* creating it (CONFIG_PCI_DYNAMIC_OF_NODES feature).
150+
* Check here for the validity of this of_node.
151+
*/
152+
if (!dev_of_node(dev))
153+
return dev_err_probe(dev, -EINVAL, "Missing of_node for device\n");
154+
155+
/* Need to be done before devm_pci_dev_create_intr_ctrl.
156+
* It allocates an IRQ and so pdev->irq is updated.
157+
*/
158+
ret = pcim_enable_device(pdev);
159+
if (ret)
160+
return ret;
161+
162+
ret = devm_pci_dev_create_intr_ctrl(pdev);
163+
if (ret)
164+
return ret;
165+
166+
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
167+
if (!data)
168+
return -ENOMEM;
169+
170+
pci_set_drvdata(pdev, data);
171+
data->dev = dev;
172+
173+
ret = lan966x_pci_load_overlay(data);
174+
if (ret)
175+
return ret;
176+
177+
pci_set_master(pdev);
178+
179+
ret = of_platform_default_populate(dev_of_node(dev), NULL, dev);
180+
if (ret)
181+
goto err_unload_overlay;
182+
183+
return 0;
184+
185+
err_unload_overlay:
186+
lan966x_pci_unload_overlay(data);
187+
return ret;
188+
}
189+
190+
static void lan966x_pci_remove(struct pci_dev *pdev)
191+
{
192+
struct lan966x_pci *data = pci_get_drvdata(pdev);
193+
194+
of_platform_depopulate(data->dev);
195+
196+
lan966x_pci_unload_overlay(data);
197+
}
198+
199+
static struct pci_device_id lan966x_pci_ids[] = {
200+
{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, 0x9660) },
201+
{ }
202+
};
203+
MODULE_DEVICE_TABLE(pci, lan966x_pci_ids);
204+
205+
static struct pci_driver lan966x_pci_driver = {
206+
.name = "mchp_lan966x_pci",
207+
.id_table = lan966x_pci_ids,
208+
.probe = lan966x_pci_probe,
209+
.remove = lan966x_pci_remove,
210+
};
211+
module_pci_driver(lan966x_pci_driver);
212+
213+
MODULE_AUTHOR("Herve Codina <[email protected]>");
214+
MODULE_DESCRIPTION("Microchip LAN966x PCI driver");
215+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)