2012-06-11 00:58:30

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 00/14] sta2x11-mfd patches

From: Davide Ciminaghi <[email protected]>

Hi,

I'm working on the implementation of the common clock framework
for the STA2X11 (aka CONNEXT) soc.
To configure, enable and disable clocks, some general purpose
registers (apb-soc-registers) must be accessed. Such registers
can be reached through bar #1 of a multifunction pci device,
which is not covered by the current version of sta2x11-mfd.
This patch series adds support for the apb-soc-registers device
and rearranges the sta2x11-mfd driver to avoid unnecessary
code duplications and to cope with the increased number of platform
devices.


Davide Ciminaghi (14):
sta2x11 mfd : also deal with PCI_DEVICE_ID_STMICRO_VIC.
sta2x11-mfd : add apb-soc regs driver and factor out common code
sta2x11-mfd : only add sta2x11_mfd if it hasn't already been added
sta2x11-mfd : platform probe: don't mind about gpio platform data
sta2x11-mfd : make enum sta2x11_mfd_plat_dev public
sta2x11-mfd, sta2x11-mfd.h: add more platform device types
sta2x11-mfd : implement apbreg_mask and sctl_mask as static inlines
sta2x11-mfd : add apb-soc-regs defines and mask function
sta2x11-mfd : add apb-soc-regs debugfs register set
sta2x11-mfd : use one lock per device instead of one lock per mfd.
sta2x11-mfd : add defines for platform devices' names
sta2x11-mfd : use defines for platform devices' names
sta2x11-mfd : add sta2x11_mfd_get_regs_data() function
sta2x11-mfd : add myself to copyright

drivers/mfd/sta2x11-mfd.c | 416 ++++++++++++++++++++++++++-------------
include/linux/mfd/sta2x11-mfd.h | 169 ++++++++++++++++-
2 files changed, 449 insertions(+), 136 deletions(-)

--
1.7.9.1


2012-06-11 00:58:32

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 01/14] sta2x11 mfd : also deal with PCI_DEVICE_ID_STMICRO_VIC.

From: Davide Ciminaghi <[email protected]>

Such device includes the apb-soc registers (bar #1), access to
which will be needed by the common clk framework implementation.

Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 120 ++++++++++++++++++++++++++++++++++++++-------
1 files changed, 102 insertions(+), 18 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index d31fed0..5c950e8 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -281,12 +281,14 @@ static int __init sta2x11_apbreg_init(void)
}

/*
- * What follows is the PCI device that hosts the above two pdevs.
+ * What follows are the PCI devices that host the above pdevs.
* Each logic block is 4kB and they are all consecutive: we use this info.
*/

-/* Bar 0 */
-enum bar0_cells {
+/* Mfd 0 device */
+
+/* Mfd 0, Bar 0 */
+enum mfd0_bar0_cells {
STA2X11_GPIO_0 = 0,
STA2X11_GPIO_1,
STA2X11_GPIO_2,
@@ -295,8 +297,8 @@ enum bar0_cells {
STA2X11_SCR,
STA2X11_TIME,
};
-/* Bar 1 */
-enum bar1_cells {
+/* Mfd 0 , Bar 1 */
+enum mfd0_bar1_cells {
STA2X11_APBREG = 0,
};
#define CELL_4K(_name, _cell) { \
@@ -330,17 +332,46 @@ static const __devinitconst struct resource apbreg_resources[] = {
#define DEV(_name, _r) \
{ .name = _name, .num_resources = ARRAY_SIZE(_r), .resources = _r, }

-static __devinitdata struct mfd_cell sta2x11_mfd_bar0[] = {
+static __devinitdata struct mfd_cell sta2x11_mfd0_bar0[] = {
DEV("sta2x11-gpio", gpio_resources), /* offset 0: we add pdata later */
DEV("sta2x11-sctl", sctl_resources),
DEV("sta2x11-scr", scr_resources),
DEV("sta2x11-time", time_resources),
};

-static __devinitdata struct mfd_cell sta2x11_mfd_bar1[] = {
+static __devinitdata struct mfd_cell sta2x11_mfd0_bar1[] = {
DEV("sta2x11-apbreg", apbreg_resources),
};

+/* Mfd 1 devices */
+
+/* Mfd 1, Bar 0 */
+enum mfd1_bar0_cells {
+ STA2X11_VIC = 0,
+};
+
+/* Mfd 1, Bar 1 */
+enum mfd1_bar1_cells {
+ STA2X11_APB_SOC_REGS = 0,
+};
+
+static const __devinitconst struct resource vic_resources[] = {
+ CELL_4K("sta2x11-vic", STA2X11_VIC),
+};
+
+static const __devinitconst struct resource apb_soc_regs_resources[] = {
+ CELL_4K("sta2x11-apb-soc-regs", STA2X11_APB_SOC_REGS),
+};
+
+static __devinitdata struct mfd_cell sta2x11_mfd1_bar0[] = {
+ DEV("sta2x11-vic", vic_resources),
+};
+
+static __devinitdata struct mfd_cell sta2x11_mfd1_bar1[] = {
+ DEV("sta2x11-apb-soc-regs", apb_soc_regs_resources),
+};
+
+
static int sta2x11_mfd_suspend(struct pci_dev *pdev, pm_message_t state)
{
pci_save_state(pdev);
@@ -363,10 +394,63 @@ static int sta2x11_mfd_resume(struct pci_dev *pdev)
return 0;
}

+struct sta2x11_mfd_bar_setup_data {
+ struct mfd_cell *cells;
+ int ncells;
+};
+
+struct sta2x11_mfd_setup_data {
+ struct sta2x11_mfd_bar_setup_data bars[2];
+};
+
+#define STA2X11_MFD0 0
+#define STA2X11_MFD1 1
+
+static struct sta2x11_mfd_setup_data mfd_setup_data[] = {
+ /* Mfd 0: gpio, sctl, scr, timers / apbregs */
+ [STA2X11_MFD0] = {
+ .bars = {
+ [0] = {
+ .cells = sta2x11_mfd0_bar0,
+ .ncells = ARRAY_SIZE(sta2x11_mfd0_bar0),
+ },
+ [1] = {
+ .cells = sta2x11_mfd0_bar1,
+ .ncells = ARRAY_SIZE(sta2x11_mfd0_bar1),
+ },
+ },
+ },
+ /* Mfd 1: vic / apb-soc-regs */
+ [STA2X11_MFD1] = {
+ .bars = {
+ [0] = {
+ .cells = sta2x11_mfd1_bar0,
+ .ncells = ARRAY_SIZE(sta2x11_mfd1_bar0),
+ },
+ [1] = {
+ .cells = sta2x11_mfd1_bar1,
+ .ncells = ARRAY_SIZE(sta2x11_mfd1_bar1),
+ },
+ },
+ },
+};
+
+static void __devinit sta2x11_mfd_setup(struct pci_dev *pdev,
+ struct sta2x11_mfd_setup_data *sd)
+{
+ int i, j;
+ for (i = 0; i < ARRAY_SIZE(sd->bars); i++)
+ for (j = 0; j < sd->bars[i].ncells; j++) {
+ sd->bars[i].cells[j].pdata_size = sizeof(pdev);
+ sd->bars[i].cells[j].platform_data = &pdev;
+ }
+}
+
static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
- int err, i;
+ int err;
+ struct sta2x11_mfd_setup_data *setup_data;
struct sta2x11_gpio_pdata *gpio_data;

dev_info(&pdev->dev, "%s\n", __func__);
@@ -381,6 +465,10 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
if (err)
dev_info(&pdev->dev, "Enable msi failed\n");

+ setup_data = pci_id->device == PCI_DEVICE_ID_STMICRO_GPIO ?
+ &mfd_setup_data[STA2X11_MFD0] :
+ &mfd_setup_data[STA2X11_MFD1];
+
/* Read gpio config data as pci device's platform data */
gpio_data = dev_get_platdata(&pdev->dev);
if (!gpio_data)
@@ -392,20 +480,15 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
pdev, &pdev);

/* platform data is the pci device for all of them */
- for (i = 0; i < ARRAY_SIZE(sta2x11_mfd_bar0); i++) {
- sta2x11_mfd_bar0[i].pdata_size = sizeof(pdev);
- sta2x11_mfd_bar0[i].platform_data = &pdev;
- }
- sta2x11_mfd_bar1[0].pdata_size = sizeof(pdev);
- sta2x11_mfd_bar1[0].platform_data = &pdev;
+ sta2x11_mfd_setup(pdev, setup_data);

/* Record this pdev before mfd_add_devices: their probe looks for it */
sta2x11_mfd_add(pdev, GFP_ATOMIC);


err = mfd_add_devices(&pdev->dev, -1,
- sta2x11_mfd_bar0,
- ARRAY_SIZE(sta2x11_mfd_bar0),
+ setup_data->bars[0].cells,
+ setup_data->bars[0].ncells,
&pdev->resource[0],
0);
if (err) {
@@ -414,8 +497,8 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
}

err = mfd_add_devices(&pdev->dev, -1,
- sta2x11_mfd_bar1,
- ARRAY_SIZE(sta2x11_mfd_bar1),
+ setup_data->bars[1].cells,
+ setup_data->bars[1].ncells,
&pdev->resource[1],
0);
if (err) {
@@ -434,6 +517,7 @@ err_disable:

static DEFINE_PCI_DEVICE_TABLE(sta2x11_mfd_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_GPIO)},
+ {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIC)},
{0,},
};

--
1.7.9.1

2012-06-11 00:59:46

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 05/14] sta2x11-mfd : make enum sta2x11_mfd_plat_dev public

From: Davide Ciminaghi <[email protected]>

This is needed to implement the sta2x11_xxxx_mask() functions as static
inlines invoking a common __sta2x11_mfd_mask.

Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 7 -------
include/linux/mfd/sta2x11-mfd.h | 7 +++++++
2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index 744bdd0..1aa9c78 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -35,13 +35,6 @@

#include <asm/sta2x11.h>

-enum sta2x11_mfd_plat_dev {
- sta2x11_sctl = 0,
- sta2x11_apbreg = 1,
- sta2x11_apb_soc_regs = 2,
- sta2x11_n_mfd_plat_devs,
-};
-
/* This describes STA2X11 MFD chip for us, we may have several */
struct sta2x11_mfd {
struct sta2x11_instance *instance;
diff --git a/include/linux/mfd/sta2x11-mfd.h b/include/linux/mfd/sta2x11-mfd.h
index d179227..2867d55 100644
--- a/include/linux/mfd/sta2x11-mfd.h
+++ b/include/linux/mfd/sta2x11-mfd.h
@@ -26,6 +26,13 @@
#include <linux/types.h>
#include <linux/pci.h>

+enum sta2x11_mfd_plat_dev {
+ sta2x11_sctl = 0,
+ sta2x11_apbreg = 1,
+ sta2x11_apb_soc_regs = 2,
+ sta2x11_n_mfd_plat_devs,
+};
+
/*
* The MFD PCI block includes the GPIO peripherals and other register blocks.
* For GPIO, we have 32*4 bits (I use "gsta" for "gpio sta2x11".)
--
1.7.9.1

2012-06-11 00:59:45

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 04/14] sta2x11-mfd : platform probe: don't mind about gpio platform data

From: Davide Ciminaghi <[email protected]>

The gpio platform driver will take care of its platform data,
let's not do any checks here.

Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 11 -----------
1 files changed, 0 insertions(+), 11 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index e004c59..744bdd0 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -465,7 +465,6 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
{
int err, i;
struct sta2x11_mfd_setup_data *setup_data;
- struct sta2x11_gpio_pdata *gpio_data;

dev_info(&pdev->dev, "%s\n", __func__);

@@ -483,16 +482,6 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
&mfd_setup_data[STA2X11_MFD0] :
&mfd_setup_data[STA2X11_MFD1];

- /* Read gpio config data as pci device's platform data */
- gpio_data = dev_get_platdata(&pdev->dev);
- if (!gpio_data)
- dev_warn(&pdev->dev, "no gpio configuration\n");
-
- dev_dbg(&pdev->dev, "%s, gpio_data = %p (%p)\n", __func__,
- gpio_data, &gpio_data);
- dev_dbg(&pdev->dev, "%s, pdev = %p (%p)\n", __func__,
- pdev, &pdev);
-
/* platform data is the pci device for all of them */
sta2x11_mfd_setup(pdev, setup_data);

--
1.7.9.1

2012-06-11 00:59:43

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 02/14] sta2x11-mfd : add apb-soc regs driver and factor out common code

From: Davide Ciminaghi <[email protected]>

Some of the functions in sta2x11-mfd.c were almost identical
for the two existing platform devices. To avoid more code
duplication while adding the apb-soc-regs driver, some changes
have been done:

* The sctl_regs and apbreg_regs fields in struct sta2x11_mfd
have been turned into just one array of pointers accessed by
device index.
* Platform probe methods have become one-liners invoking a
common probe with the device's index as second parameter.
* For loops have been inserted where the same operations
were performed for each of the two bars of a pci device.

Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 152 ++++++++++++++++++++++++---------------------
1 files changed, 80 insertions(+), 72 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index 5c950e8..69c7bdc 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -35,13 +35,19 @@

#include <asm/sta2x11.h>

+enum sta2x11_mfd_plat_dev {
+ sta2x11_sctl = 0,
+ sta2x11_apbreg = 1,
+ sta2x11_apb_soc_regs = 2,
+ sta2x11_n_mfd_plat_devs,
+};
+
/* This describes STA2X11 MFD chip for us, we may have several */
struct sta2x11_mfd {
struct sta2x11_instance *instance;
spinlock_t lock;
struct list_head list;
- void __iomem *sctl_regs;
- void __iomem *apbreg_regs;
+ void __iomem *regs[sta2x11_n_mfd_plat_devs];
};

static LIST_HEAD(sta2x11_mfd_list);
@@ -106,21 +112,22 @@ u32 sta2x11_sctl_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
u32 r;
unsigned long flags;
+ void __iomem *regs = mfd->regs[sta2x11_sctl];

if (!mfd) {
dev_warn(&pdev->dev, ": can't access sctl regs\n");
return 0;
}
- if (!mfd->sctl_regs) {
+ if (!regs) {
dev_warn(&pdev->dev, ": system ctl not initialized\n");
return 0;
}
spin_lock_irqsave(&mfd->lock, flags);
- r = readl(mfd->sctl_regs + reg);
+ r = readl(regs + reg);
r &= ~mask;
r |= val;
if (mask)
- writel(r, mfd->sctl_regs + reg);
+ writel(r, regs + reg);
spin_unlock_irqrestore(&mfd->lock, flags);
return r;
}
@@ -131,21 +138,22 @@ u32 sta2x11_apbreg_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
u32 r;
unsigned long flags;
+ void __iomem *regs = mfd->regs[sta2x11_apbreg];

if (!mfd) {
dev_warn(&pdev->dev, ": can't access apb regs\n");
return 0;
}
- if (!mfd->apbreg_regs) {
+ if (!regs) {
dev_warn(&pdev->dev, ": apb bridge not initialized\n");
return 0;
}
spin_lock_irqsave(&mfd->lock, flags);
- r = readl(mfd->apbreg_regs + reg);
+ r = readl(regs + reg);
r &= ~mask;
r |= val;
if (mask)
- writel(r, mfd->apbreg_regs + reg);
+ writel(r, regs + reg);
spin_unlock_irqrestore(&mfd->lock, flags);
return r;
}
@@ -180,15 +188,29 @@ static struct debugfs_regset32 apbreg_regset = {
.nregs = ARRAY_SIZE(sta2x11_apbreg_regs),
};

-static struct dentry *sta2x11_sctl_debugfs;
-static struct dentry *sta2x11_apbreg_debugfs;
+static struct dentry *sta2x11_mfd_debugfs[sta2x11_n_mfd_plat_devs];

-/* Probe for the two platform devices */
-static int sta2x11_sctl_probe(struct platform_device *dev)
+static struct debugfs_regset32 *sta2x11_mfd_regset[sta2x11_n_mfd_plat_devs] = {
+ [sta2x11_sctl] = &sctl_regset,
+ [sta2x11_apbreg] = &apbreg_regset,
+};
+
+static const char *sta2x11_mfd_names[sta2x11_n_mfd_plat_devs] = {
+ [sta2x11_sctl] = "sta2x11-sctl",
+ [sta2x11_apbreg] = "sta2x11-apbreg",
+ [sta2x11_apb_soc_regs] = "sta2x11-apb-soc-regs",
+};
+
+/* Probe for the three platform devices */
+
+static int sta2x11_mfd_platform_probe(struct platform_device *dev,
+ enum sta2x11_mfd_plat_dev index)
{
struct pci_dev **pdev;
struct sta2x11_mfd *mfd;
struct resource *res;
+ const char *name = sta2x11_mfd_names[index];
+ struct debugfs_regset32 *regset = sta2x11_mfd_regset[index];

pdev = dev->dev.platform_data;
mfd = sta2x11_mfd_find(*pdev);
@@ -199,59 +221,37 @@ static int sta2x11_sctl_probe(struct platform_device *dev)
if (!res)
return -ENOMEM;

- if (!request_mem_region(res->start, resource_size(res),
- "sta2x11-sctl"))
+ if (!request_mem_region(res->start, resource_size(res), name))
return -EBUSY;

- mfd->sctl_regs = ioremap(res->start, resource_size(res));
- if (!mfd->sctl_regs) {
+ mfd->regs[index] = ioremap(res->start, resource_size(res));
+ if (!mfd->regs[index]) {
release_mem_region(res->start, resource_size(res));
return -ENOMEM;
}
- sctl_regset.base = mfd->sctl_regs;
- sta2x11_sctl_debugfs = debugfs_create_regset32("sta2x11-sctl",
- S_IFREG | S_IRUGO,
- NULL, &sctl_regset);
+ regset->base = mfd->regs[index];
+ sta2x11_mfd_debugfs[index] = debugfs_create_regset32(name,
+ S_IFREG | S_IRUGO,
+ NULL, regset);
return 0;
}

-static int sta2x11_apbreg_probe(struct platform_device *dev)
+static int sta2x11_sctl_probe(struct platform_device *dev)
{
- struct pci_dev **pdev;
- struct sta2x11_mfd *mfd;
- struct resource *res;
-
- pdev = dev->dev.platform_data;
- dev_dbg(&dev->dev, "%s: pdata is %p\n", __func__, pdev);
- dev_dbg(&dev->dev, "%s: *pdata is %p\n", __func__, *pdev);
-
- mfd = sta2x11_mfd_find(*pdev);
- if (!mfd)
- return -ENODEV;
-
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENOMEM;
-
- if (!request_mem_region(res->start, resource_size(res),
- "sta2x11-apbreg"))
- return -EBUSY;
+ return sta2x11_mfd_platform_probe(dev, sta2x11_sctl);
+}

- mfd->apbreg_regs = ioremap(res->start, resource_size(res));
- if (!mfd->apbreg_regs) {
- release_mem_region(res->start, resource_size(res));
- return -ENOMEM;
- }
- dev_dbg(&dev->dev, "%s: regbase %p\n", __func__, mfd->apbreg_regs);
+static int sta2x11_apbreg_probe(struct platform_device *dev)
+{
+ return sta2x11_mfd_platform_probe(dev, sta2x11_apbreg);
+}

- apbreg_regset.base = mfd->apbreg_regs;
- sta2x11_apbreg_debugfs = debugfs_create_regset32("sta2x11-apbreg",
- S_IFREG | S_IRUGO,
- NULL, &apbreg_regset);
- return 0;
+static int sta2x11_apb_soc_regs_probe(struct platform_device *dev)
+{
+ return sta2x11_mfd_platform_probe(dev, sta2x11_apb_soc_regs);
}

-/* The two platform drivers */
+/* The three platform drivers */
static struct platform_driver sta2x11_sctl_platform_driver = {
.driver = {
.name = "sta2x11-sctl",
@@ -280,6 +280,20 @@ static int __init sta2x11_apbreg_init(void)
return platform_driver_register(&sta2x11_platform_driver);
}

+static struct platform_driver sta2x11_apb_soc_regs_platform_driver = {
+ .driver = {
+ .name = "sta2x11-apb-soc-regs",
+ .owner = THIS_MODULE,
+ },
+ .probe = sta2x11_apb_soc_regs_probe,
+};
+
+static int __init sta2x11_apb_soc_regs_init(void)
+{
+ pr_info("%s\n", __func__);
+ return platform_driver_register(&sta2x11_apb_soc_regs_platform_driver);
+}
+
/*
* What follows are the PCI devices that host the above pdevs.
* Each logic block is 4kB and they are all consecutive: we use this info.
@@ -449,7 +463,7 @@ static void __devinit sta2x11_mfd_setup(struct pci_dev *pdev,
static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
- int err;
+ int err, i;
struct sta2x11_mfd_setup_data *setup_data;
struct sta2x11_gpio_pdata *gpio_data;

@@ -485,25 +499,18 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
/* Record this pdev before mfd_add_devices: their probe looks for it */
sta2x11_mfd_add(pdev, GFP_ATOMIC);

-
- err = mfd_add_devices(&pdev->dev, -1,
- setup_data->bars[0].cells,
- setup_data->bars[0].ncells,
- &pdev->resource[0],
- 0);
- if (err) {
- dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err);
- goto err_disable;
- }
-
- err = mfd_add_devices(&pdev->dev, -1,
- setup_data->bars[1].cells,
- setup_data->bars[1].ncells,
- &pdev->resource[1],
- 0);
- if (err) {
- dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err);
- goto err_disable;
+ /* Just 2 bars for all mfd's at present */
+ for (i = 0; i < 2; i++) {
+ err = mfd_add_devices(&pdev->dev, -1,
+ setup_data->bars[i].cells,
+ setup_data->bars[i].ncells,
+ &pdev->resource[i],
+ 0);
+ if (err) {
+ dev_err(&pdev->dev,
+ "mfd_add_devices[%d] failed: %d\n", i, err);
+ goto err_disable;
+ }
}

return 0;
@@ -543,6 +550,7 @@ static int __init sta2x11_mfd_init(void)
*/
subsys_initcall(sta2x11_apbreg_init);
subsys_initcall(sta2x11_sctl_init);
+subsys_initcall(sta2x11_apb_soc_regs_init);
rootfs_initcall(sta2x11_mfd_init);

MODULE_LICENSE("GPL v2");
--
1.7.9.1

2012-06-11 00:59:42

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 06/14] sta2x11-mfd, sta2x11-mfd.h: add more platform device types

From: Davide Ciminaghi <[email protected]>


Signed-off-by: Davide Ciminaghi <[email protected]>
---
include/linux/mfd/sta2x11-mfd.h | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/linux/mfd/sta2x11-mfd.h b/include/linux/mfd/sta2x11-mfd.h
index 2867d55..4b2667a 100644
--- a/include/linux/mfd/sta2x11-mfd.h
+++ b/include/linux/mfd/sta2x11-mfd.h
@@ -28,8 +28,12 @@

enum sta2x11_mfd_plat_dev {
sta2x11_sctl = 0,
- sta2x11_apbreg = 1,
- sta2x11_apb_soc_regs = 2,
+ sta2x11_gpio,
+ sta2x11_scr,
+ sta2x11_time,
+ sta2x11_apbreg,
+ sta2x11_apb_soc_regs,
+ sta2x11_vic,
sta2x11_n_mfd_plat_devs,
};

--
1.7.9.1

2012-06-11 00:59:40

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 03/14] sta2x11-mfd : only add sta2x11_mfd if it hasn't already been added

From: Davide Ciminaghi <[email protected]>

The pci probe method is called twice now, so we have to call
sta2x11_mfd_add() only once to avoid a -EBUSY error.

Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index 69c7bdc..e004c59 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -497,7 +497,8 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
sta2x11_mfd_setup(pdev, setup_data);

/* Record this pdev before mfd_add_devices: their probe looks for it */
- sta2x11_mfd_add(pdev, GFP_ATOMIC);
+ if (!sta2x11_mfd_find(pdev))
+ sta2x11_mfd_add(pdev, GFP_ATOMIC);

/* Just 2 bars for all mfd's at present */
for (i = 0; i < 2; i++) {
--
1.7.9.1

2012-06-11 00:59:38

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 07/14] sta2x11-mfd : implement apbreg_mask and sctl_mask as static inlines

From: Davide Ciminaghi <[email protected]>

The apbreg_mask and sctl_mask functions were almost identical,
so they were turned into one-liners invoking a common
__sta2x11_mfd_mask() with the platform device's index as last
parameter.

Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 35 +++++------------------------------
include/linux/mfd/sta2x11-mfd.h | 15 +++++++++++++--
2 files changed, 18 insertions(+), 32 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index 1aa9c78..16d340c 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -99,13 +99,14 @@ static int __devexit mfd_remove(struct pci_dev *pdev)
return 0;
}

-/* These two functions are exported and are not expected to fail */
-u32 sta2x11_sctl_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
+/* This function is exported and is not expected to fail */
+u32 __sta2x11_mfd_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val,
+ enum sta2x11_mfd_plat_dev index)
{
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
u32 r;
unsigned long flags;
- void __iomem *regs = mfd->regs[sta2x11_sctl];
+ void __iomem *regs = mfd->regs[index];

if (!mfd) {
dev_warn(&pdev->dev, ": can't access sctl regs\n");
@@ -124,33 +125,7 @@ u32 sta2x11_sctl_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
spin_unlock_irqrestore(&mfd->lock, flags);
return r;
}
-EXPORT_SYMBOL(sta2x11_sctl_mask);
-
-u32 sta2x11_apbreg_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
-{
- struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
- u32 r;
- unsigned long flags;
- void __iomem *regs = mfd->regs[sta2x11_apbreg];
-
- if (!mfd) {
- dev_warn(&pdev->dev, ": can't access apb regs\n");
- return 0;
- }
- if (!regs) {
- dev_warn(&pdev->dev, ": apb bridge not initialized\n");
- return 0;
- }
- spin_lock_irqsave(&mfd->lock, flags);
- r = readl(regs + reg);
- r &= ~mask;
- r |= val;
- if (mask)
- writel(r, regs + reg);
- spin_unlock_irqrestore(&mfd->lock, flags);
- return r;
-}
-EXPORT_SYMBOL(sta2x11_apbreg_mask);
+EXPORT_SYMBOL(__sta2x11_mfd_mask);

/* Two debugfs files, for our registers (FIXME: one instance only) */
#define REG(regname) {.name = #regname, .offset = SCTL_ ## regname}
diff --git a/include/linux/mfd/sta2x11-mfd.h b/include/linux/mfd/sta2x11-mfd.h
index 4b2667a..09a94d3 100644
--- a/include/linux/mfd/sta2x11-mfd.h
+++ b/include/linux/mfd/sta2x11-mfd.h
@@ -37,6 +37,9 @@ enum sta2x11_mfd_plat_dev {
sta2x11_n_mfd_plat_devs,
};

+extern u32
+__sta2x11_mfd_mask(struct pci_dev *, u32, u32, u32, enum sta2x11_mfd_plat_dev);
+
/*
* The MFD PCI block includes the GPIO peripherals and other register blocks.
* For GPIO, we have 32*4 bits (I use "gsta" for "gpio sta2x11".)
@@ -193,7 +196,11 @@ struct sta2x11_gpio_pdata {
* The APB bridge has its own registers, needed by our users as well.
* They are accessed with the following read/mask/write function.
*/
-u32 sta2x11_apbreg_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val);
+static inline u32
+sta2x11_apbreg_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
+{
+ return __sta2x11_mfd_mask(pdev, reg, mask, val, sta2x11_apbreg);
+}

/* CAN and MLB */
#define APBREG_BSR 0x00 /* Bridge Status Reg */
@@ -222,7 +229,11 @@ u32 sta2x11_apbreg_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val);
* The system controller has its own registers. Some of these are accessed
* by out users as well, using the following read/mask/write/function
*/
-u32 sta2x11_sctl_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val);
+static inline
+u32 sta2x11_sctl_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
+{
+ return __sta2x11_mfd_mask(pdev, reg, mask, val, sta2x11_sctl);
+}

#define SCTL_SCCTL 0x00 /* System controller control register */
#define SCTL_ARMCFG 0x04 /* ARM configuration register */
--
1.7.9.1

2012-06-11 00:59:36

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 09/14] sta2x11-mfd : add apb-soc-regs debugfs register set

From: Davide Ciminaghi <[email protected]>


Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 72 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index 16d340c..110404f 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -156,11 +156,83 @@ static struct debugfs_regset32 apbreg_regset = {
.nregs = ARRAY_SIZE(sta2x11_apbreg_regs),
};

+#define REG(regname) {.name = #regname, .offset = regname}
+static struct debugfs_reg32 sta2x11_apb_soc_regs_regs[] = {
+ REG(PCIE_EP1_FUNC3_0_INTR_REG), REG(PCIE_EP1_FUNC7_4_INTR_REG),
+ REG(PCIE_EP2_FUNC3_0_INTR_REG), REG(PCIE_EP2_FUNC7_4_INTR_REG),
+ REG(PCIE_EP3_FUNC3_0_INTR_REG), REG(PCIE_EP3_FUNC7_4_INTR_REG),
+ REG(PCIE_EP4_FUNC3_0_INTR_REG), REG(PCIE_EP4_FUNC7_4_INTR_REG),
+ REG(PCIE_INTR_ENABLE0_REG), REG(PCIE_INTR_ENABLE1_REG),
+ REG(PCIE_EP1_FUNC_TC_REG), REG(PCIE_EP2_FUNC_TC_REG),
+ REG(PCIE_EP3_FUNC_TC_REG), REG(PCIE_EP4_FUNC_TC_REG),
+ REG(PCIE_EP1_FUNC_F_REG), REG(PCIE_EP2_FUNC_F_REG),
+ REG(PCIE_EP3_FUNC_F_REG), REG(PCIE_EP4_FUNC_F_REG),
+ REG(PCIE_PAB_AMBA_SW_RST_REG), REG(PCIE_PM_STATUS_0_PORT_0_4),
+ REG(PCIE_PM_STATUS_7_0_EP1), REG(PCIE_PM_STATUS_7_0_EP2),
+ REG(PCIE_PM_STATUS_7_0_EP3), REG(PCIE_PM_STATUS_7_0_EP4),
+ REG(PCIE_DEV_ID_0_EP1_REG), REG(PCIE_CC_REV_ID_0_EP1_REG),
+ REG(PCIE_DEV_ID_1_EP1_REG), REG(PCIE_CC_REV_ID_1_EP1_REG),
+ REG(PCIE_DEV_ID_2_EP1_REG), REG(PCIE_CC_REV_ID_2_EP1_REG),
+ REG(PCIE_DEV_ID_3_EP1_REG), REG(PCIE_CC_REV_ID_3_EP1_REG),
+ REG(PCIE_DEV_ID_4_EP1_REG), REG(PCIE_CC_REV_ID_4_EP1_REG),
+ REG(PCIE_DEV_ID_5_EP1_REG), REG(PCIE_CC_REV_ID_5_EP1_REG),
+ REG(PCIE_DEV_ID_6_EP1_REG), REG(PCIE_CC_REV_ID_6_EP1_REG),
+ REG(PCIE_DEV_ID_7_EP1_REG), REG(PCIE_CC_REV_ID_7_EP1_REG),
+ REG(PCIE_DEV_ID_0_EP2_REG), REG(PCIE_CC_REV_ID_0_EP2_REG),
+ REG(PCIE_DEV_ID_1_EP2_REG), REG(PCIE_CC_REV_ID_1_EP2_REG),
+ REG(PCIE_DEV_ID_2_EP2_REG), REG(PCIE_CC_REV_ID_2_EP2_REG),
+ REG(PCIE_DEV_ID_3_EP2_REG), REG(PCIE_CC_REV_ID_3_EP2_REG),
+ REG(PCIE_DEV_ID_4_EP2_REG), REG(PCIE_CC_REV_ID_4_EP2_REG),
+ REG(PCIE_DEV_ID_5_EP2_REG), REG(PCIE_CC_REV_ID_5_EP2_REG),
+ REG(PCIE_DEV_ID_6_EP2_REG), REG(PCIE_CC_REV_ID_6_EP2_REG),
+ REG(PCIE_DEV_ID_7_EP2_REG), REG(PCIE_CC_REV_ID_7_EP2_REG),
+ REG(PCIE_DEV_ID_0_EP3_REG), REG(PCIE_CC_REV_ID_0_EP3_REG),
+ REG(PCIE_DEV_ID_1_EP3_REG), REG(PCIE_CC_REV_ID_1_EP3_REG),
+ REG(PCIE_DEV_ID_2_EP3_REG), REG(PCIE_CC_REV_ID_2_EP3_REG),
+ REG(PCIE_DEV_ID_3_EP3_REG), REG(PCIE_CC_REV_ID_3_EP3_REG),
+ REG(PCIE_DEV_ID_4_EP3_REG), REG(PCIE_CC_REV_ID_4_EP3_REG),
+ REG(PCIE_DEV_ID_5_EP3_REG), REG(PCIE_CC_REV_ID_5_EP3_REG),
+ REG(PCIE_DEV_ID_6_EP3_REG), REG(PCIE_CC_REV_ID_6_EP3_REG),
+ REG(PCIE_DEV_ID_7_EP3_REG), REG(PCIE_CC_REV_ID_7_EP3_REG),
+ REG(PCIE_DEV_ID_0_EP4_REG), REG(PCIE_CC_REV_ID_0_EP4_REG),
+ REG(PCIE_DEV_ID_1_EP4_REG), REG(PCIE_CC_REV_ID_1_EP4_REG),
+ REG(PCIE_DEV_ID_2_EP4_REG), REG(PCIE_CC_REV_ID_2_EP4_REG),
+ REG(PCIE_DEV_ID_3_EP4_REG), REG(PCIE_CC_REV_ID_3_EP4_REG),
+ REG(PCIE_DEV_ID_4_EP4_REG), REG(PCIE_CC_REV_ID_4_EP4_REG),
+ REG(PCIE_DEV_ID_5_EP4_REG), REG(PCIE_CC_REV_ID_5_EP4_REG),
+ REG(PCIE_DEV_ID_6_EP4_REG), REG(PCIE_CC_REV_ID_6_EP4_REG),
+ REG(PCIE_DEV_ID_7_EP4_REG), REG(PCIE_CC_REV_ID_7_EP4_REG),
+ REG(PCIE_SUBSYS_VEN_ID_REG), REG(PCIE_COMMON_CLOCK_CONFIG_0_4_0),
+ REG(PCIE_MIPHYP_SSC_EN_REG), REG(PCIE_MIPHYP_ADDR_REG),
+ REG(PCIE_L1_ASPM_READY_REG), REG(PCIE_EXT_CFG_RDY_REG),
+ REG(PCIE_SoC_INT_ROUTER_STATUS0_REG),
+ REG(PCIE_SoC_INT_ROUTER_STATUS1_REG),
+ REG(PCIE_SoC_INT_ROUTER_STATUS2_REG),
+ REG(PCIE_SoC_INT_ROUTER_STATUS3_REG),
+ REG(DMA_IP_CTRL_REG), REG(DISP_BRIDGE_PU_PD_CTRL_REG),
+ REG(VIP_PU_PD_CTRL_REG), REG(USB_MLB_PU_PD_CTRL_REG),
+ REG(SDIO_PU_PD_MISCFUNC_CTRL_REG1), REG(SDIO_PU_PD_MISCFUNC_CTRL_REG2),
+ REG(UART_PU_PD_CTRL_REG), REG(ARM_Lock), REG(SYS_IO_CHAR_REG1),
+ REG(SYS_IO_CHAR_REG2), REG(SATA_CORE_ID_REG), REG(SATA_CTRL_REG),
+ REG(I2C_HSFIX_MISC_REG), REG(SPARE2_RESERVED), REG(SPARE3_RESERVED),
+ REG(MASTER_LOCK_REG), REG(SYSTEM_CONFIG_STATUS_REG),
+ REG(MSP_CLK_CTRL_REG), REG(COMPENSATION_REG1), REG(COMPENSATION_REG2),
+ REG(COMPENSATION_REG3), REG(TEST_CTL_REG),
+};
+#undef REG
+
+static struct debugfs_regset32 apb_soc_regs_regset = {
+ .regs = sta2x11_apb_soc_regs_regs,
+ .nregs = ARRAY_SIZE(sta2x11_apb_soc_regs_regs),
+};
+
+
static struct dentry *sta2x11_mfd_debugfs[sta2x11_n_mfd_plat_devs];

static struct debugfs_regset32 *sta2x11_mfd_regset[sta2x11_n_mfd_plat_devs] = {
[sta2x11_sctl] = &sctl_regset,
[sta2x11_apbreg] = &apbreg_regset,
+ [sta2x11_apb_soc_regs] = &apb_soc_regs_regset,
};

static const char *sta2x11_mfd_names[sta2x11_n_mfd_plat_devs] = {
--
1.7.9.1

2012-06-11 00:59:34

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 08/14] sta2x11-mfd : add apb-soc-regs defines and mask function

From: Davide Ciminaghi <[email protected]>


Signed-off-by: Davide Ciminaghi <[email protected]>
---
include/linux/mfd/sta2x11-mfd.h | 130 +++++++++++++++++++++++++++++++++++++++
1 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/include/linux/mfd/sta2x11-mfd.h b/include/linux/mfd/sta2x11-mfd.h
index 09a94d3..4d85879 100644
--- a/include/linux/mfd/sta2x11-mfd.h
+++ b/include/linux/mfd/sta2x11-mfd.h
@@ -343,4 +343,134 @@ u32 sta2x11_sctl_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
#define SCTL_SCPEREN1_I2C3 (1 << 16)
#define SCTL_SCPEREN1_USB_PHY (1 << 17)

+/*
+ * APB-SOC registers
+ */
+static inline
+u32 sta2x11_apb_soc_regs_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
+{
+ return __sta2x11_mfd_mask(pdev, reg, mask, val, sta2x11_apb_soc_regs);
+}
+
+#define PCIE_EP1_FUNC3_0_INTR_REG 0x000
+#define PCIE_EP1_FUNC7_4_INTR_REG 0x004
+#define PCIE_EP2_FUNC3_0_INTR_REG 0x008
+#define PCIE_EP2_FUNC7_4_INTR_REG 0x00c
+#define PCIE_EP3_FUNC3_0_INTR_REG 0x010
+#define PCIE_EP3_FUNC7_4_INTR_REG 0x014
+#define PCIE_EP4_FUNC3_0_INTR_REG 0x018
+#define PCIE_EP4_FUNC7_4_INTR_REG 0x01c
+#define PCIE_INTR_ENABLE0_REG 0x020
+#define PCIE_INTR_ENABLE1_REG 0x024
+#define PCIE_EP1_FUNC_TC_REG 0x028
+#define PCIE_EP2_FUNC_TC_REG 0x02c
+#define PCIE_EP3_FUNC_TC_REG 0x030
+#define PCIE_EP4_FUNC_TC_REG 0x034
+#define PCIE_EP1_FUNC_F_REG 0x038
+#define PCIE_EP2_FUNC_F_REG 0x03c
+#define PCIE_EP3_FUNC_F_REG 0x040
+#define PCIE_EP4_FUNC_F_REG 0x044
+#define PCIE_PAB_AMBA_SW_RST_REG 0x048
+#define PCIE_PM_STATUS_0_PORT_0_4 0x04c
+#define PCIE_PM_STATUS_7_0_EP1 0x050
+#define PCIE_PM_STATUS_7_0_EP2 0x054
+#define PCIE_PM_STATUS_7_0_EP3 0x058
+#define PCIE_PM_STATUS_7_0_EP4 0x05c
+#define PCIE_DEV_ID_0_EP1_REG 0x060
+#define PCIE_CC_REV_ID_0_EP1_REG 0x064
+#define PCIE_DEV_ID_1_EP1_REG 0x068
+#define PCIE_CC_REV_ID_1_EP1_REG 0x06c
+#define PCIE_DEV_ID_2_EP1_REG 0x070
+#define PCIE_CC_REV_ID_2_EP1_REG 0x074
+#define PCIE_DEV_ID_3_EP1_REG 0x078
+#define PCIE_CC_REV_ID_3_EP1_REG 0x07c
+#define PCIE_DEV_ID_4_EP1_REG 0x080
+#define PCIE_CC_REV_ID_4_EP1_REG 0x084
+#define PCIE_DEV_ID_5_EP1_REG 0x088
+#define PCIE_CC_REV_ID_5_EP1_REG 0x08c
+#define PCIE_DEV_ID_6_EP1_REG 0x090
+#define PCIE_CC_REV_ID_6_EP1_REG 0x094
+#define PCIE_DEV_ID_7_EP1_REG 0x098
+#define PCIE_CC_REV_ID_7_EP1_REG 0x09c
+#define PCIE_DEV_ID_0_EP2_REG 0x0a0
+#define PCIE_CC_REV_ID_0_EP2_REG 0x0a4
+#define PCIE_DEV_ID_1_EP2_REG 0x0a8
+#define PCIE_CC_REV_ID_1_EP2_REG 0x0ac
+#define PCIE_DEV_ID_2_EP2_REG 0x0b0
+#define PCIE_CC_REV_ID_2_EP2_REG 0x0b4
+#define PCIE_DEV_ID_3_EP2_REG 0x0b8
+#define PCIE_CC_REV_ID_3_EP2_REG 0x0bc
+#define PCIE_DEV_ID_4_EP2_REG 0x0c0
+#define PCIE_CC_REV_ID_4_EP2_REG 0x0c4
+#define PCIE_DEV_ID_5_EP2_REG 0x0c8
+#define PCIE_CC_REV_ID_5_EP2_REG 0x0cc
+#define PCIE_DEV_ID_6_EP2_REG 0x0d0
+#define PCIE_CC_REV_ID_6_EP2_REG 0x0d4
+#define PCIE_DEV_ID_7_EP2_REG 0x0d8
+#define PCIE_CC_REV_ID_7_EP2_REG 0x0dC
+#define PCIE_DEV_ID_0_EP3_REG 0x0e0
+#define PCIE_CC_REV_ID_0_EP3_REG 0x0e4
+#define PCIE_DEV_ID_1_EP3_REG 0x0e8
+#define PCIE_CC_REV_ID_1_EP3_REG 0x0ec
+#define PCIE_DEV_ID_2_EP3_REG 0x0f0
+#define PCIE_CC_REV_ID_2_EP3_REG 0x0f4
+#define PCIE_DEV_ID_3_EP3_REG 0x0f8
+#define PCIE_CC_REV_ID_3_EP3_REG 0x0fc
+#define PCIE_DEV_ID_4_EP3_REG 0x100
+#define PCIE_CC_REV_ID_4_EP3_REG 0x104
+#define PCIE_DEV_ID_5_EP3_REG 0x108
+#define PCIE_CC_REV_ID_5_EP3_REG 0x10c
+#define PCIE_DEV_ID_6_EP3_REG 0x110
+#define PCIE_CC_REV_ID_6_EP3_REG 0x114
+#define PCIE_DEV_ID_7_EP3_REG 0x118
+#define PCIE_CC_REV_ID_7_EP3_REG 0x11c
+#define PCIE_DEV_ID_0_EP4_REG 0x120
+#define PCIE_CC_REV_ID_0_EP4_REG 0x124
+#define PCIE_DEV_ID_1_EP4_REG 0x128
+#define PCIE_CC_REV_ID_1_EP4_REG 0x12c
+#define PCIE_DEV_ID_2_EP4_REG 0x130
+#define PCIE_CC_REV_ID_2_EP4_REG 0x134
+#define PCIE_DEV_ID_3_EP4_REG 0x138
+#define PCIE_CC_REV_ID_3_EP4_REG 0x13c
+#define PCIE_DEV_ID_4_EP4_REG 0x140
+#define PCIE_CC_REV_ID_4_EP4_REG 0x144
+#define PCIE_DEV_ID_5_EP4_REG 0x148
+#define PCIE_CC_REV_ID_5_EP4_REG 0x14c
+#define PCIE_DEV_ID_6_EP4_REG 0x150
+#define PCIE_CC_REV_ID_6_EP4_REG 0x154
+#define PCIE_DEV_ID_7_EP4_REG 0x158
+#define PCIE_CC_REV_ID_7_EP4_REG 0x15c
+#define PCIE_SUBSYS_VEN_ID_REG 0x160
+#define PCIE_COMMON_CLOCK_CONFIG_0_4_0 0x164
+#define PCIE_MIPHYP_SSC_EN_REG 0x168
+#define PCIE_MIPHYP_ADDR_REG 0x16c
+#define PCIE_L1_ASPM_READY_REG 0x170
+#define PCIE_EXT_CFG_RDY_REG 0x174
+#define PCIE_SoC_INT_ROUTER_STATUS0_REG 0x178
+#define PCIE_SoC_INT_ROUTER_STATUS1_REG 0x17c
+#define PCIE_SoC_INT_ROUTER_STATUS2_REG 0x180
+#define PCIE_SoC_INT_ROUTER_STATUS3_REG 0x184
+#define DMA_IP_CTRL_REG 0x324
+#define DISP_BRIDGE_PU_PD_CTRL_REG 0x328
+#define VIP_PU_PD_CTRL_REG 0x32c
+#define USB_MLB_PU_PD_CTRL_REG 0x330
+#define SDIO_PU_PD_MISCFUNC_CTRL_REG1 0x334
+#define SDIO_PU_PD_MISCFUNC_CTRL_REG2 0x338
+#define UART_PU_PD_CTRL_REG 0x33c
+#define ARM_Lock 0x340
+#define SYS_IO_CHAR_REG1 0x344
+#define SYS_IO_CHAR_REG2 0x348
+#define SATA_CORE_ID_REG 0x34c
+#define SATA_CTRL_REG 0x350
+#define I2C_HSFIX_MISC_REG 0x354
+#define SPARE2_RESERVED 0x358
+#define SPARE3_RESERVED 0x35c
+#define MASTER_LOCK_REG 0x368
+#define SYSTEM_CONFIG_STATUS_REG 0x36c
+#define MSP_CLK_CTRL_REG 0x39c
+#define COMPENSATION_REG1 0x3c4
+#define COMPENSATION_REG2 0x3c8
+#define COMPENSATION_REG3 0x3cc
+#define TEST_CTL_REG 0x3d0
+
#endif /* __STA2X11_MFD_H */
--
1.7.9.1

2012-06-11 00:59:32

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 10/14] sta2x11-mfd : use one lock per device instead of one lock per mfd.

From: Davide Ciminaghi <[email protected]>

The lock is used to implement atomic operations on each platform
device's registers, so it looks reasonable having one lock per
device instead of one common lock for all the devices belonging
to the same sta2x11 instance.

Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index 110404f..cc20a79 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -38,7 +38,7 @@
/* This describes STA2X11 MFD chip for us, we may have several */
struct sta2x11_mfd {
struct sta2x11_instance *instance;
- spinlock_t lock;
+ spinlock_t lock[sta2x11_n_mfd_plat_devs];
struct list_head list;
void __iomem *regs[sta2x11_n_mfd_plat_devs];
};
@@ -70,6 +70,7 @@ static struct sta2x11_mfd *sta2x11_mfd_find(struct pci_dev *pdev)

static int __devinit sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
{
+ int i;
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
struct sta2x11_instance *instance;

@@ -82,7 +83,8 @@ static int __devinit sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
if (!mfd)
return -ENOMEM;
INIT_LIST_HEAD(&mfd->list);
- spin_lock_init(&mfd->lock);
+ for (i = 0; i < ARRAY_SIZE(mfd->lock); i++)
+ spin_lock_init(&mfd->lock[i]);
mfd->instance = instance;
list_add(&mfd->list, &sta2x11_mfd_list);
return 0;
@@ -116,13 +118,13 @@ u32 __sta2x11_mfd_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val,
dev_warn(&pdev->dev, ": system ctl not initialized\n");
return 0;
}
- spin_lock_irqsave(&mfd->lock, flags);
+ spin_lock_irqsave(&mfd->lock[index], flags);
r = readl(regs + reg);
r &= ~mask;
r |= val;
if (mask)
writel(r, regs + reg);
- spin_unlock_irqrestore(&mfd->lock, flags);
+ spin_unlock_irqrestore(&mfd->lock[index], flags);
return r;
}
EXPORT_SYMBOL(__sta2x11_mfd_mask);
--
1.7.9.1

2012-06-11 00:59:30

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 11/14] sta2x11-mfd : add defines for platform devices' names

From: Davide Ciminaghi <[email protected]>

Since there are now many mfd platform devices, using defines for their
names seems to be a better solution (avoids wasting time in case of
typos, makes it easier to change the name of a device, ....).

Signed-off-by: Davide Ciminaghi <[email protected]>
---
include/linux/mfd/sta2x11-mfd.h | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/include/linux/mfd/sta2x11-mfd.h b/include/linux/mfd/sta2x11-mfd.h
index 4d85879..85b2c20 100644
--- a/include/linux/mfd/sta2x11-mfd.h
+++ b/include/linux/mfd/sta2x11-mfd.h
@@ -37,6 +37,14 @@ enum sta2x11_mfd_plat_dev {
sta2x11_n_mfd_plat_devs,
};

+#define STA2X11_MFD_SCTL_NAME "sta2x11-sctl"
+#define STA2X11_MFD_GPIO_NAME "sta2x11-gpio"
+#define STA2X11_MFD_SCR_NAME "sta2x11-scr"
+#define STA2X11_MFD_TIME_NAME "sta2x11-time"
+#define STA2X11_MFD_APBREG_NAME "sta2x11-apbreg"
+#define STA2X11_MFD_APB_SOC_REGS_NAME "sta2x11-apb-soc-regs"
+#define STA2X11_MFD_VIC_NAME "sta2x11-vic"
+
extern u32
__sta2x11_mfd_mask(struct pci_dev *, u32, u32, u32, enum sta2x11_mfd_plat_dev);

--
1.7.9.1

2012-06-11 00:59:27

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 12/14] sta2x11-mfd : use defines for platform devices' names

From: Davide Ciminaghi <[email protected]>


Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 42 ++++++++++++++++++++++--------------------
1 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index cc20a79..aca0bc7 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -238,9 +238,9 @@ static struct debugfs_regset32 *sta2x11_mfd_regset[sta2x11_n_mfd_plat_devs] = {
};

static const char *sta2x11_mfd_names[sta2x11_n_mfd_plat_devs] = {
- [sta2x11_sctl] = "sta2x11-sctl",
- [sta2x11_apbreg] = "sta2x11-apbreg",
- [sta2x11_apb_soc_regs] = "sta2x11-apb-soc-regs",
+ [sta2x11_sctl] = STA2X11_MFD_SCTL_NAME,
+ [sta2x11_apbreg] = STA2X11_MFD_APBREG_NAME,
+ [sta2x11_apb_soc_regs] = STA2X11_MFD_APB_SOC_REGS_NAME,
};

/* Probe for the three platform devices */
@@ -296,7 +296,7 @@ static int sta2x11_apb_soc_regs_probe(struct platform_device *dev)
/* The three platform drivers */
static struct platform_driver sta2x11_sctl_platform_driver = {
.driver = {
- .name = "sta2x11-sctl",
+ .name = STA2X11_MFD_SCTL_NAME,
.owner = THIS_MODULE,
},
.probe = sta2x11_sctl_probe,
@@ -310,7 +310,7 @@ static int __init sta2x11_sctl_init(void)

static struct platform_driver sta2x11_platform_driver = {
.driver = {
- .name = "sta2x11-apbreg",
+ .name = STA2X11_MFD_APBREG_NAME,
.owner = THIS_MODULE,
},
.probe = sta2x11_apbreg_probe,
@@ -324,7 +324,7 @@ static int __init sta2x11_apbreg_init(void)

static struct platform_driver sta2x11_apb_soc_regs_platform_driver = {
.driver = {
- .name = "sta2x11-apb-soc-regs",
+ .name = STA2X11_MFD_APB_SOC_REGS_NAME,
.owner = THIS_MODULE,
},
.probe = sta2x11_apb_soc_regs_probe,
@@ -365,38 +365,40 @@ enum mfd0_bar1_cells {

static const __devinitconst struct resource gpio_resources[] = {
{
- .name = "sta2x11_gpio", /* 4 consecutive cells, 1 driver */
+ /* 4 consecutive cells, 1 driver */
+ .name = STA2X11_MFD_GPIO_NAME,
.start = 0,
.end = (4 * 4096) - 1,
.flags = IORESOURCE_MEM,
}
};
static const __devinitconst struct resource sctl_resources[] = {
- CELL_4K("sta2x11-sctl", STA2X11_SCTL),
+ CELL_4K(STA2X11_MFD_SCTL_NAME, STA2X11_SCTL),
};
static const __devinitconst struct resource scr_resources[] = {
- CELL_4K("sta2x11-scr", STA2X11_SCR),
+ CELL_4K(STA2X11_MFD_SCR_NAME, STA2X11_SCR),
};
static const __devinitconst struct resource time_resources[] = {
- CELL_4K("sta2x11-time", STA2X11_TIME),
+ CELL_4K(STA2X11_MFD_TIME_NAME, STA2X11_TIME),
};

static const __devinitconst struct resource apbreg_resources[] = {
- CELL_4K("sta2x11-apbreg", STA2X11_APBREG),
+ CELL_4K(STA2X11_MFD_APBREG_NAME, STA2X11_APBREG),
};

#define DEV(_name, _r) \
{ .name = _name, .num_resources = ARRAY_SIZE(_r), .resources = _r, }

static __devinitdata struct mfd_cell sta2x11_mfd0_bar0[] = {
- DEV("sta2x11-gpio", gpio_resources), /* offset 0: we add pdata later */
- DEV("sta2x11-sctl", sctl_resources),
- DEV("sta2x11-scr", scr_resources),
- DEV("sta2x11-time", time_resources),
+ /* offset 0: we add pdata later */
+ DEV(STA2X11_MFD_GPIO_NAME, gpio_resources),
+ DEV(STA2X11_MFD_SCTL_NAME, sctl_resources),
+ DEV(STA2X11_MFD_SCR_NAME, scr_resources),
+ DEV(STA2X11_MFD_TIME_NAME, time_resources),
};

static __devinitdata struct mfd_cell sta2x11_mfd0_bar1[] = {
- DEV("sta2x11-apbreg", apbreg_resources),
+ DEV(STA2X11_MFD_APBREG_NAME, apbreg_resources),
};

/* Mfd 1 devices */
@@ -412,19 +414,19 @@ enum mfd1_bar1_cells {
};

static const __devinitconst struct resource vic_resources[] = {
- CELL_4K("sta2x11-vic", STA2X11_VIC),
+ CELL_4K(STA2X11_MFD_VIC_NAME, STA2X11_VIC),
};

static const __devinitconst struct resource apb_soc_regs_resources[] = {
- CELL_4K("sta2x11-apb-soc-regs", STA2X11_APB_SOC_REGS),
+ CELL_4K(STA2X11_MFD_APB_SOC_REGS_NAME, STA2X11_APB_SOC_REGS),
};

static __devinitdata struct mfd_cell sta2x11_mfd1_bar0[] = {
- DEV("sta2x11-vic", vic_resources),
+ DEV(STA2X11_MFD_VIC_NAME, vic_resources),
};

static __devinitdata struct mfd_cell sta2x11_mfd1_bar1[] = {
- DEV("sta2x11-apb-soc-regs", apb_soc_regs_resources),
+ DEV(STA2X11_MFD_APB_SOC_REGS_NAME, apb_soc_regs_resources),
};


--
1.7.9.1

2012-06-11 00:59:25

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 14/14] sta2x11-mfd : add myself to copyright

From: Davide Ciminaghi <[email protected]>


Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index 9404988..d4bf010 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2009-2011 Wind River Systems, Inc.
- * Copyright (c) 2011 ST Microelectronics (Alessandro Rubini)
+ * Copyright (c) 2011 ST Microelectronics (Alessandro Rubini, Davide Ciminaghi)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
--
1.7.9.1

2012-06-11 00:59:23

by Davide Ciminaghi

[permalink] [raw]
Subject: [PATCH 13/14] sta2x11-mfd : add sta2x11_mfd_get_regs_data() function

From: Davide Ciminaghi <[email protected]>

The common clock framework implementation needs to access
some of the sctl and apb-soc registers to configure, enable
and disable clocks.

In particular, a couple of predefined clocks (mux and gated)
need to be initialized with the virtual address of the clock's
controlling register and the address of a spinlock used to
protect against races.
This function exports such data for all the mfd cells.

Signed-off-by: Davide Ciminaghi <[email protected]>
---
drivers/mfd/sta2x11-mfd.c | 22 ++++++++++++++++++++++
include/linux/mfd/sta2x11-mfd.h | 5 +++++
2 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index aca0bc7..9404988 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -129,6 +129,28 @@ u32 __sta2x11_mfd_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val,
}
EXPORT_SYMBOL(__sta2x11_mfd_mask);

+extern int sta2x11_mfd_get_regs_data(struct platform_device *dev,
+ enum sta2x11_mfd_plat_dev index,
+ void __iomem **regs,
+ spinlock_t **lock)
+{
+ struct pci_dev *pdev = *(struct pci_dev **)(dev->dev.platform_data);
+ struct sta2x11_mfd *mfd;
+
+ if (!pdev)
+ return -ENODEV;
+ mfd = sta2x11_mfd_find(pdev);
+ if (!mfd)
+ return -ENODEV;
+ if (index >= sta2x11_n_mfd_plat_devs)
+ return -ENODEV;
+ *regs = mfd->regs[index];
+ *lock = &mfd->lock[index];
+ pr_debug("%s %d *regs = %p\n", __func__, __LINE__, *regs);
+ return *regs ? 0 : -ENODEV;
+}
+EXPORT_SYMBOL(sta2x11_mfd_get_regs_data);
+
/* Two debugfs files, for our registers (FIXME: one instance only) */
#define REG(regname) {.name = #regname, .offset = SCTL_ ## regname}
static struct debugfs_reg32 sta2x11_sctl_regs[] = {
diff --git a/include/linux/mfd/sta2x11-mfd.h b/include/linux/mfd/sta2x11-mfd.h
index 85b2c20..9de20fd 100644
--- a/include/linux/mfd/sta2x11-mfd.h
+++ b/include/linux/mfd/sta2x11-mfd.h
@@ -481,4 +481,9 @@ u32 sta2x11_apb_soc_regs_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
#define COMPENSATION_REG3 0x3cc
#define TEST_CTL_REG 0x3d0

+extern int sta2x11_mfd_get_regs_data(struct platform_device *pdev,
+ enum sta2x11_mfd_plat_dev index,
+ void __iomem **regs,
+ spinlock_t **lock);
+
#endif /* __STA2X11_MFD_H */
--
1.7.9.1