162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * RDC321x MFD southbridge driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
662306a36Sopenharmony_ci * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#include <linux/module.h>
962306a36Sopenharmony_ci#include <linux/kernel.h>
1062306a36Sopenharmony_ci#include <linux/platform_device.h>
1162306a36Sopenharmony_ci#include <linux/pci.h>
1262306a36Sopenharmony_ci#include <linux/mfd/core.h>
1362306a36Sopenharmony_ci#include <linux/mfd/rdc321x.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistatic struct rdc321x_wdt_pdata rdc321x_wdt_pdata;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistatic const struct resource rdc321x_wdt_resource[] = {
1862306a36Sopenharmony_ci	{
1962306a36Sopenharmony_ci		.name	= "wdt-reg",
2062306a36Sopenharmony_ci		.start	= RDC321X_WDT_CTRL,
2162306a36Sopenharmony_ci		.end	= RDC321X_WDT_CTRL + 0x3,
2262306a36Sopenharmony_ci		.flags	= IORESOURCE_IO,
2362306a36Sopenharmony_ci	}
2462306a36Sopenharmony_ci};
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistatic struct rdc321x_gpio_pdata rdc321x_gpio_pdata = {
2762306a36Sopenharmony_ci	.max_gpios	= RDC321X_NUM_GPIO,
2862306a36Sopenharmony_ci};
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistatic const struct resource rdc321x_gpio_resources[] = {
3162306a36Sopenharmony_ci	{
3262306a36Sopenharmony_ci		.name	= "gpio-reg1",
3362306a36Sopenharmony_ci		.start	= RDC321X_GPIO_CTRL_REG1,
3462306a36Sopenharmony_ci		.end	= RDC321X_GPIO_CTRL_REG1 + 0x7,
3562306a36Sopenharmony_ci		.flags	= IORESOURCE_IO,
3662306a36Sopenharmony_ci	}, {
3762306a36Sopenharmony_ci		.name	= "gpio-reg2",
3862306a36Sopenharmony_ci		.start	= RDC321X_GPIO_CTRL_REG2,
3962306a36Sopenharmony_ci		.end	= RDC321X_GPIO_CTRL_REG2 + 0x7,
4062306a36Sopenharmony_ci		.flags	= IORESOURCE_IO,
4162306a36Sopenharmony_ci	}
4262306a36Sopenharmony_ci};
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistatic const struct mfd_cell rdc321x_sb_cells[] = {
4562306a36Sopenharmony_ci	{
4662306a36Sopenharmony_ci		.name		= "rdc321x-wdt",
4762306a36Sopenharmony_ci		.resources	= rdc321x_wdt_resource,
4862306a36Sopenharmony_ci		.num_resources	= ARRAY_SIZE(rdc321x_wdt_resource),
4962306a36Sopenharmony_ci		.platform_data	= &rdc321x_wdt_pdata,
5062306a36Sopenharmony_ci		.pdata_size	= sizeof(rdc321x_wdt_pdata),
5162306a36Sopenharmony_ci	}, {
5262306a36Sopenharmony_ci		.name		= "rdc321x-gpio",
5362306a36Sopenharmony_ci		.resources	= rdc321x_gpio_resources,
5462306a36Sopenharmony_ci		.num_resources	= ARRAY_SIZE(rdc321x_gpio_resources),
5562306a36Sopenharmony_ci		.platform_data	= &rdc321x_gpio_pdata,
5662306a36Sopenharmony_ci		.pdata_size	= sizeof(rdc321x_gpio_pdata),
5762306a36Sopenharmony_ci	},
5862306a36Sopenharmony_ci};
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic int rdc321x_sb_probe(struct pci_dev *pdev,
6162306a36Sopenharmony_ci					const struct pci_device_id *ent)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	int err;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	err = pci_enable_device(pdev);
6662306a36Sopenharmony_ci	if (err) {
6762306a36Sopenharmony_ci		dev_err(&pdev->dev, "failed to enable device\n");
6862306a36Sopenharmony_ci		return err;
6962306a36Sopenharmony_ci	}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	rdc321x_gpio_pdata.sb_pdev = pdev;
7262306a36Sopenharmony_ci	rdc321x_wdt_pdata.sb_pdev = pdev;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	return devm_mfd_add_devices(&pdev->dev, -1,
7562306a36Sopenharmony_ci				    rdc321x_sb_cells,
7662306a36Sopenharmony_ci				    ARRAY_SIZE(rdc321x_sb_cells),
7762306a36Sopenharmony_ci				    NULL, 0, NULL);
7862306a36Sopenharmony_ci}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistatic const struct pci_device_id rdc321x_sb_table[] = {
8162306a36Sopenharmony_ci	{ PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) },
8262306a36Sopenharmony_ci	{}
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, rdc321x_sb_table);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_cistatic struct pci_driver rdc321x_sb_driver = {
8762306a36Sopenharmony_ci	.name		= "RDC321x Southbridge",
8862306a36Sopenharmony_ci	.id_table	= rdc321x_sb_table,
8962306a36Sopenharmony_ci	.probe		= rdc321x_sb_probe,
9062306a36Sopenharmony_ci};
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cimodule_pci_driver(rdc321x_sb_driver);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ciMODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
9562306a36Sopenharmony_ciMODULE_LICENSE("GPL");
9662306a36Sopenharmony_ciMODULE_DESCRIPTION("RDC R-321x MFD southbridge driver");
97