public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [platforms: PATCH v3 00/12] Armada 7k8k GPIO support
@ 2019-01-17 11:15 Marcin Wojtas
  2019-01-17 11:15 ` [platforms: PATCH v3 01/12] Marvell/Library: ArmadaSoCDescLib: Add GPIO information Marcin Wojtas
                   ` (12 more replies)
  0 siblings, 13 replies; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

Hi,

I submit v3 of the GPIO patchset for the Marvell SoCs.
The changes are not significant and they address all the comments
from the previous version. Please find the details in the changelog
below.

Patches are available in the github:
https://github.com/MarvellEmbeddedProcessors/edk2-open-platform/commits/gpio-upstream-r20190117

I am looking forward to your feedback.

Best regards,
Marcin

Changelog:
v2->v3:
* 1,2,4,12/12
   - Add Leif's RB  

* 3/12
  - Change MvGpio.h to be library header (Library/MvGpioLib.h)
  - Introduce MvGpioLib library
  - Add PCA_ID enums in this patch (instead from PCA9xxx addition)

* 5,6/12
  - Use PCA_ID enum from the beginning

* 7/12
  - Use static global variable and allocate it only only once
  - s/I2C/GPIO/

* 8/12
  - Simplify error path after changing approach to not freeing
    already allocated GpioDescription in MvBoardDescDxe
  - Change signature to non-generic

* 10/12
  - Simplify error path after changing approach to not freeing
    already allocated GpioDescription in MvBoardDescDxe
  - No need to update PCA_ID in this patch

v1->v2:
* All
  - rebase on top of the master branch and Xenon changes

* 1/12
  - s/AP/AP806/ in order to avoid confusion
  - drop desc/DESC usage and improve variables naming
  - use GPIO_CONTROLLER from EmbeddedGpio.h instead of custom MV_SOC_GPIO
  - update commit message

* 2,3,4,5/12
  - drop desc/DESC usage and improve variables naming
  - drop reference to I2c and use GpioExpander
  - improve commit logs

* 6/12
  - drop desc/DESC usage and improve variables naming
  - drop reference to I2c and use GpioExpander
  - remove global variable - same as for other interfaces the consumer
    is responsible for avoiding memory leak

* 7/12
  - use MV_GPIO_ prefix
  - switch to EMBEDDED_GPIO
  - remove custom Marvell GPIO Protocol and types
  - add subroutine to MvGpioGetProtocol and more coments to clarify the code
  - add driver types and related enums in other commits

* 8/12
  - extend error path in the entry point, rename variables
  - use MV_GPIO_ prefix
  - switch to EMBEDDED_GPIO
  - remove custom Marvell GPIO Protocol and types
  - replace '!!' expression for obtaining pin state
  - remove BIT() macro
  - use generic mDevicePathTemplate name
  - put validate function under '#if !defined(MDEPKG_NDEBUG)' and
     call from inside ASSERT_EFI_ERROR, add comment
  - update commit message
  - add common enum for describing controllers
  - change authorship

- 9/12
  - Add Leif's RB

* 10/12
  - same modifications as 8/12
  - use I2C flags directly and remove PCA95XX_OPERATION enum
  - add common enum for describing controllers

* 11/12
  - Add Leif's RB

* 12/12
  - Add local headers
  - Make STATIC names more generic
  - s/GetInitializerForType/NonDiscoverableDeviceInitializerGet/
  - Use global enum for McBin GPIO controller


Marcin Wojtas (12):
  Marvell/Library: ArmadaSoCDescLib: Add GPIO information
  Marvell/Library: ArmadaBoardDescLib: Add GPIO information
  Marvell/Library: Introduce MvGpioLib class
  SolidRun/Armada80x0McBin: Extend board description library with GPIO
  Marvell/Armada70x0Db: Extend board description library with GPIO
  Marvell/Armada80x0Db: Extend board description library with GPIO
  Marvell/Drivers: MvBoardDesc: Extend protocol with GPIO support
  Marvell/Drivers: MvGpioDxe: Introduce platform GPIO driver
  Marvell/Drivers: I2c: Use common header for macros
  Marvell/Drivers: MvPca95xxDxe: Introduce GPIO expander driver
  Marvell/Armada7k8k: Enable GPIO drivers compilation
  Marvell/Armada7k8k: Introduce NonDiscoverable device init routines

 Silicon/Marvell/Marvell.dec                                                                   |   2 +
 Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc                                                 |   3 +
 Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc                                                |   7 +-
 Platform/Marvell/Armada80x0Db/Armada80x0Db.dsc                                                |   3 +
 Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.dsc                                         |   3 +
 Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.inf           |   1 +
 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf               |  49 ++
 Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.inf           |   1 +
 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf               |  50 ++
 Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.inf |   1 +
 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf           |  50 ++
 Silicon/Marvell/Armada7k8k/Drivers/PlatInitDxe/PlatInitDxe.inf                                |   1 +
 Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.inf              |   1 +
 Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.inf                                          |   1 +
 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf                                          |  44 ++
 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf                                    |  45 ++
 Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf                                             |   1 +
 Silicon/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf                                           |   1 +
 Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.inf                             |   1 +
 Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf                                           |   1 +
 Silicon/Marvell/Library/ComPhyLib/ComPhyLib.inf                                               |   1 +
 Silicon/Marvell/Library/IcuLib/IcuLib.inf                                                     |   1 +
 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf                                               |  32 +
 Silicon/Marvell/Library/UtmiPhyLib/UtmiPhyLib.inf                                             |   1 +
 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h                 |  23 +
 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h                 |  28 +
 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h             |  20 +
 Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.h                |  10 +
 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h                                            |  49 ++
 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h                                      |  65 ++
 Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.h                                         |  10 -
 Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.h                                               |  17 +-
 Silicon/Marvell/Include/Library/ArmadaBoardDescLib.h                                          |  23 +
 Silicon/Marvell/Include/Library/ArmadaSoCDescLib.h                                            |  12 +
 Silicon/Marvell/Include/Library/MvGpioLib.h                                                   |  68 +++
 Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h                                      |  28 +
 Silicon/Marvell/Include/Protocol/BoardDesc.h                                                  |   8 +
 Silicon/Marvell/Include/Protocol/MvI2c.h                                                      |  31 +
 Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c             |  24 +
 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c                 |  96 +++
 Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c             |  30 +
 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c                 | 106 ++++
 Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.c   |  17 +
 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c             |  71 +++
 Silicon/Marvell/Applications/EepromCmd/EepromCmd.c                                            |   5 +-
 Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.c                |  39 ++
 Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c                                            |  50 ++
 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c                                            | 353 +++++++++++
 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c                                      | 645 ++++++++++++++++++++
 Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.c                                         |   3 +-
 Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.c                                               |   4 +-
 Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.c                               |  13 +-
 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c                                                 | 132 ++++
 Platform/Marvell/Armada70x0Db/Armada70x0Db.fdf.inc                                            |   2 +
 Platform/Marvell/Armada80x0Db/Armada80x0Db.fdf.inc                                            |   2 +
 Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.fdf.inc                                     |   2 +
 56 files changed, 2249 insertions(+), 38 deletions(-)
 create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
 create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
 create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
 create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
 create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
 create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
 create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h
 create mode 100644 Silicon/Marvell/Include/Library/MvGpioLib.h
 create mode 100644 Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h
 create mode 100644 Silicon/Marvell/Include/Protocol/MvI2c.h
 create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
 create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
 create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c
 create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c

-- 
2.7.4



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 01/12] Marvell/Library: ArmadaSoCDescLib: Add GPIO information
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:15 ` [platforms: PATCH v3 02/12] Marvell/Library: ArmadaBoardDescLib: " Marcin Wojtas
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

This patch introduces new library callback (ArmadaSoCGpioGet ()),
which dynamically allocates and fills EmbeddedGpio's
GPIO_CONTROLLER structure with the SoC description of GPIO controllers.

Because the library header is indirectly used in many modules,
update all dependencies after including EmbeddedGpio.h.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.inf |  1 +
 Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.inf |  1 +
 Silicon/Marvell/Armada7k8k/Drivers/PlatInitDxe/PlatInitDxe.inf                      |  1 +
 Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.inf    |  1 +
 Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.inf                                |  1 +
 Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf                                   |  1 +
 Silicon/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf                                 |  1 +
 Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf                                 |  1 +
 Silicon/Marvell/Library/ComPhyLib/ComPhyLib.inf                                     |  1 +
 Silicon/Marvell/Library/IcuLib/IcuLib.inf                                           |  1 +
 Silicon/Marvell/Library/UtmiPhyLib/UtmiPhyLib.inf                                   |  1 +
 Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.h      | 10 +++++
 Silicon/Marvell/Include/Library/ArmadaSoCDescLib.h                                  | 12 ++++++
 Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.c      | 39 ++++++++++++++++++++
 14 files changed, 72 insertions(+)

diff --git a/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.inf b/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.inf
index b26f55b..c995515 100644
--- a/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.inf
+++ b/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.inf
@@ -25,6 +25,7 @@
   Armada70x0DbBoardDescLib.c
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.inf b/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.inf
index 2d39d96..786b7f0 100644
--- a/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.inf
+++ b/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.inf
@@ -25,6 +25,7 @@
   Armada80x0DbBoardDescLib.c
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Silicon/Marvell/Armada7k8k/Drivers/PlatInitDxe/PlatInitDxe.inf b/Silicon/Marvell/Armada7k8k/Drivers/PlatInitDxe/PlatInitDxe.inf
index 5503463..e707fe9 100644
--- a/Silicon/Marvell/Armada7k8k/Drivers/PlatInitDxe/PlatInitDxe.inf
+++ b/Silicon/Marvell/Armada7k8k/Drivers/PlatInitDxe/PlatInitDxe.inf
@@ -25,6 +25,7 @@
   PlatInitDxe.c
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.inf b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.inf
index 2b73b73..48a320c 100644
--- a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.inf
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.inf
@@ -24,6 +24,7 @@
   Armada7k8kSoCDescLib.c
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.inf b/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.inf
index 0b93948..0b641fe 100644
--- a/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.inf
+++ b/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.inf
@@ -42,6 +42,7 @@
   MvBoardDescDxe.h
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf b/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf
index 0eef350..e5bd370 100755
--- a/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf
+++ b/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf
@@ -41,6 +41,7 @@
   MvI2cDxe.c
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
diff --git a/Silicon/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf b/Silicon/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf
index 739576f..8a877da 100644
--- a/Silicon/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf
+++ b/Silicon/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf
@@ -45,6 +45,7 @@
 [Packages]
   ArmPkg/ArmPkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf
index 00c738a..09c5842 100644
--- a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf
+++ b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf
@@ -35,6 +35,7 @@
   XenonSdMmcOverride.h
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Silicon/Marvell/Library/ComPhyLib/ComPhyLib.inf b/Silicon/Marvell/Library/ComPhyLib/ComPhyLib.inf
index 36f498b..c360edd 100644
--- a/Silicon/Marvell/Library/ComPhyLib/ComPhyLib.inf
+++ b/Silicon/Marvell/Library/ComPhyLib/ComPhyLib.inf
@@ -41,6 +41,7 @@
 [Packages]
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
   ArmPkg/ArmPkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Silicon/Marvell/Library/IcuLib/IcuLib.inf b/Silicon/Marvell/Library/IcuLib/IcuLib.inf
index 0010141..ea662be 100644
--- a/Silicon/Marvell/Library/IcuLib/IcuLib.inf
+++ b/Silicon/Marvell/Library/IcuLib/IcuLib.inf
@@ -24,6 +24,7 @@
   IcuLib.c
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Silicon/Marvell/Library/UtmiPhyLib/UtmiPhyLib.inf b/Silicon/Marvell/Library/UtmiPhyLib/UtmiPhyLib.inf
index e2381f4..805a057 100644
--- a/Silicon/Marvell/Library/UtmiPhyLib/UtmiPhyLib.inf
+++ b/Silicon/Marvell/Library/UtmiPhyLib/UtmiPhyLib.inf
@@ -41,6 +41,7 @@
 [Packages]
   ArmPkg/ArmPkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.h b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.h
index c14b985..bfc8639 100644
--- a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.h
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.h
@@ -22,6 +22,7 @@
 // Common macros
 //
 #define MV_SOC_CP_BASE(Cp)               (0xF2000000 + ((Cp) * 0x2000000))
+#define MV_SOC_AP806_COUNT               1
 
 //
 // Platform description of AHCI controllers
@@ -38,6 +39,15 @@
 #define MV_SOC_COMPHY_MUX_BITS           4
 
 //
+// Platform description of GPIO controllers
+//
+#define MV_SOC_AP806_GPIO_BASE           0xF06F5040
+#define MV_SOC_AP806_GPIO_PIN_COUNT      20
+#define MV_SOC_GPIO_PER_CP_COUNT         2
+#define MV_SOC_CP_GPIO_BASE(Gpio)        (0x440100 + ((Gpio) * 0x40))
+#define MV_SOC_CP_GPIO_PIN_COUNT(Gpio)   ((Gpio) == 0 ? 32 : 31)
+
+//
 // Platform description of I2C controllers
 //
 #define MV_SOC_I2C_PER_CP_COUNT          2
diff --git a/Silicon/Marvell/Include/Library/ArmadaSoCDescLib.h b/Silicon/Marvell/Include/Library/ArmadaSoCDescLib.h
index cdfb51b..26b075a 100644
--- a/Silicon/Marvell/Include/Library/ArmadaSoCDescLib.h
+++ b/Silicon/Marvell/Include/Library/ArmadaSoCDescLib.h
@@ -17,6 +17,8 @@
 #include <Library/MvComPhyLib.h>
 #include <Library/NonDiscoverableDeviceRegistrationLib.h>
 
+#include <Protocol/EmbeddedGpio.h>
+
 //
 // ComPhy SoC description
 //
@@ -46,6 +48,16 @@ ArmadaSoCDescCpBaseGet (
   );
 
 //
+// GPIO devices description template definition
+//
+EFI_STATUS
+EFIAPI
+ArmadaSoCGpioGet (
+  IN OUT GPIO_CONTROLLER  **SoCGpioDescription,
+  IN OUT UINTN             *Count
+  );
+
+//
 // I2C
 //
 typedef struct {
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.c b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.c
index 6902fda..5b72c20 100644
--- a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.c
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.c
@@ -74,6 +74,45 @@ ArmadaSoCDescCpBaseGet (
 
 EFI_STATUS
 EFIAPI
+ArmadaSoCGpioGet (
+  IN OUT GPIO_CONTROLLER  **SoCGpioDescription,
+  IN OUT UINTN             *Count
+  )
+{
+  GPIO_CONTROLLER *GpioInstance;
+  UINTN CpCount, CpIndex, Index;
+
+  CpCount = FixedPcdGet8 (PcdMaxCpCount);
+
+  *Count = CpCount * MV_SOC_GPIO_PER_CP_COUNT + MV_SOC_AP806_COUNT;
+  GpioInstance = AllocateZeroPool (*Count * sizeof (GPIO_CONTROLLER));
+  if (GpioInstance == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Cannot allocate memory\n", __FUNCTION__));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *SoCGpioDescription = GpioInstance;
+
+  /* AP806 GPIO controller */
+  GpioInstance->RegisterBase = MV_SOC_AP806_GPIO_BASE;
+  GpioInstance->InternalGpioCount = MV_SOC_AP806_GPIO_PIN_COUNT;
+  GpioInstance++;
+
+  /* CP110 GPIO controllers */
+  for (CpIndex = 0; CpIndex < CpCount; CpIndex++) {
+    for (Index = 0; Index < MV_SOC_GPIO_PER_CP_COUNT; Index++) {
+      GpioInstance->RegisterBase = MV_SOC_CP_BASE (CpIndex) +
+                                   MV_SOC_CP_GPIO_BASE (Index);
+      GpioInstance->InternalGpioCount = MV_SOC_CP_GPIO_PIN_COUNT (Index);
+      GpioInstance++;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
 ArmadaSoCDescI2cGet (
   IN OUT MV_SOC_I2C_DESC  **I2cDesc,
   IN OUT UINTN             *DescCount
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 02/12] Marvell/Library: ArmadaBoardDescLib: Add GPIO information
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
  2019-01-17 11:15 ` [platforms: PATCH v3 01/12] Marvell/Library: ArmadaSoCDescLib: Add GPIO information Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:15 ` [platforms: PATCH v3 03/12] Marvell/Library: Introduce MvGpioLib class Marcin Wojtas
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

This patch extends library with GPIO devices per-board
description. Both embedded SoC controllers and
I2C IO expanders are supported. Add a helper routine
for obtaining information about the latter.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 Silicon/Marvell/Include/Library/ArmadaBoardDescLib.h | 23 ++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/Silicon/Marvell/Include/Library/ArmadaBoardDescLib.h b/Silicon/Marvell/Include/Library/ArmadaBoardDescLib.h
index 3fe2988..6ec5ace 100644
--- a/Silicon/Marvell/Include/Library/ArmadaBoardDescLib.h
+++ b/Silicon/Marvell/Include/Library/ArmadaBoardDescLib.h
@@ -25,6 +25,29 @@ typedef struct {
 } MV_BOARD_COMPHY_DESC;
 
 //
+// GPIO devices per-board description
+//
+typedef struct {
+  UINTN ChipId;
+  UINTN I2cAddress;
+  UINTN I2cBus;
+} MV_GPIO_EXPANDER;
+
+typedef struct {
+  GPIO_CONTROLLER  *SoCGpio;
+  UINTN             GpioDeviceCount;
+  MV_GPIO_EXPANDER *GpioExpanders;
+  UINTN             GpioExpanderCount;
+} MV_BOARD_GPIO_DESCRIPTION;
+
+EFI_STATUS
+EFIAPI
+ArmadaBoardGpioExpanderGet (
+  IN OUT MV_GPIO_EXPANDER **GpioExpanders,
+  IN OUT UINTN             *GpioExpanderCount
+  );
+
+//
 // I2C devices per-board description
 //
 typedef struct {
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 03/12] Marvell/Library: Introduce MvGpioLib class
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
  2019-01-17 11:15 ` [platforms: PATCH v3 01/12] Marvell/Library: ArmadaSoCDescLib: Add GPIO information Marcin Wojtas
  2019-01-17 11:15 ` [platforms: PATCH v3 02/12] Marvell/Library: ArmadaBoardDescLib: " Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:33   ` Leif Lindholm
  2019-01-17 11:15 ` [platforms: PATCH v3 04/12] SolidRun/Armada80x0McBin: Extend board description library with GPIO Marcin Wojtas
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

Following patches will add two drivers that are capable
of producing the generic EMBEDDED_GPIO protocol. In order
to handle a situation, when the consumer module attempts
to locate and open a proper protocol, add a library
helper function.

In order to ease description of used GPIO pins and controllers
of the Armada 7k8k platforms, add the common enum types.

Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
 Silicon/Marvell/Marvell.dec                     |   1 +
 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf |  32 +++++
 Silicon/Marvell/Include/Library/MvGpioLib.h     |  68 ++++++++++
 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c   | 132 ++++++++++++++++++++
 4 files changed, 233 insertions(+)
 create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
 create mode 100644 Silicon/Marvell/Include/Library/MvGpioLib.h
 create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c

diff --git a/Silicon/Marvell/Marvell.dec b/Silicon/Marvell/Marvell.dec
index 616624e..ac922a0 100644
--- a/Silicon/Marvell/Marvell.dec
+++ b/Silicon/Marvell/Marvell.dec
@@ -63,6 +63,7 @@
   ArmadaBoardDescLib|Include/Library/ArmadaBoardDescLib.h
   ArmadaIcuLib|Include/Library/ArmadaIcuLib.h
   ArmadaSoCDescLib|Include/Library/ArmadaSoCDescLib.h
+  MvGpioLib|Include/Library/MvGpioLib.h
   SampleAtResetLib|Include/Library/SampleAtResetLib.h
 
 [Protocols]
diff --git a/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
new file mode 100644
index 0000000..3bc54ce
--- /dev/null
+++ b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
@@ -0,0 +1,32 @@
+## @file
+#
+#  Copyright (C) 2018, Marvell International Ltd. and its affiliates<BR>
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+#  IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = MvGpioLib
+  FILE_GUID                      = f4386b44-6bc2-4fa1-9989-8513bbb22692
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MvGpioLib
+
+[Sources]
+  MvGpioLib.c
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+  DebugLib
diff --git a/Silicon/Marvell/Include/Library/MvGpioLib.h b/Silicon/Marvell/Include/Library/MvGpioLib.h
new file mode 100644
index 0000000..a14acdf
--- /dev/null
+++ b/Silicon/Marvell/Include/Library/MvGpioLib.h
@@ -0,0 +1,68 @@
+/**
+*
+*  Copyright (C) 2018, Marvell International Ltd. and its affiliates.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+#ifndef __MV_GPIO_LIB_H__
+#define __MV_GPIO_LIB_H__
+
+#include <Protocol/EmbeddedGpio.h>
+
+typedef enum {
+  MV_GPIO_DRIVER_TYPE_SOC_CONTROLLER,
+  MV_GPIO_DRIVER_TYPE_PCA95XX,
+} MV_GPIO_DRIVER_TYPE;
+
+typedef enum {
+  MV_GPIO_AP806_CONTROLLER0,
+  MV_GPIO_CP0_CONTROLLER0,
+  MV_GPIO_CP0_CONTROLLER1,
+  MV_GPIO_CP1_CONTROLLER0,
+  MV_GPIO_CP1_CONTROLLER1,
+  MV_GPIO_CP2_CONTROLLER0,
+  MV_GPIO_CP2_CONTROLLER1,
+} MV_GPIO_SOC_CONTROLLER_TYPE;
+
+typedef enum {
+  PCA9505_ID,
+  PCA9534_ID,
+  PCA9535_ID,
+  PCA9536_ID,
+  PCA9537_ID,
+  PCA9538_ID,
+  PCA9539_ID,
+  PCA9554_ID,
+  PCA9555_ID,
+  PCA9556_ID,
+  PCA9557_ID,
+  PCA95XX_MAX_ID,
+} MV_GPIO_EXPANDER_TYPE_PCA95XX;
+
+typedef struct {
+  VENDOR_DEVICE_PATH        Header;
+  MV_GPIO_DRIVER_TYPE       GpioDriverType;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} MV_GPIO_DEVICE_PATH;
+
+typedef struct {
+  UINTN    ControllerId;
+  UINTN    PinNumber;
+  BOOLEAN  ActiveHigh;
+} MV_GPIO_PIN;
+
+EFI_STATUS
+EFIAPI
+MvGpioGetProtocol (
+  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
+  IN OUT EMBEDDED_GPIO        **GpioProtocol
+  );
+
+#endif // __MV_GPIO_LIB_H__
diff --git a/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
new file mode 100644
index 0000000..a95d5ae
--- /dev/null
+++ b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
@@ -0,0 +1,132 @@
+/**
+*
+*  Copyright (C) 2018, Marvell International Ltd. and its affiliates.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/MvGpioLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EmbeddedGpio.h>
+
+/*
+ * Check if the driver type matches the requested value.
+ * In case of the success open the GPIO protocol and return.
+ */
+STATIC
+EFI_STATUS
+MvGpioFindMatchingDriver (
+  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
+  IN     EFI_HANDLE             HandleBuffer,
+  IN     EFI_DEVICE_PATH       *DevicePath,
+  IN OUT EMBEDDED_GPIO        **GpioProtocol
+  )
+{
+  MV_GPIO_DEVICE_PATH *GpioDevicePath;
+  EFI_STATUS           Status;
+
+  while (!IsDevicePathEndType (DevicePath)) {
+    /* Check if GpioDriverType matches one found in the device path */
+    GpioDevicePath = (MV_GPIO_DEVICE_PATH *)DevicePath;
+    if (GpioDevicePath->GpioDriverType != GpioDriverType) {
+      DevicePath = NextDevicePathNode (DevicePath);
+      continue;
+    }
+
+    /*
+     * Open GpioProtocol. With EFI_OPEN_PROTOCOL_GET_PROTOCOL attribute
+     * the consumer is not obliged to call CloseProtocol.
+     */
+    Status = gBS->OpenProtocol (HandleBuffer,
+                    &gEmbeddedGpioProtocolGuid,
+                    (VOID **)GpioProtocol,
+                    gImageHandle,
+                    NULL,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+    return Status;
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/*
+ * Select desired protocol producer upon MV_GPIO_DRIVER_TYPE
+ * field of driver's MV_GPIO_DEVICE_PATH.
+ */
+EFI_STATUS
+EFIAPI
+MvGpioGetProtocol (
+  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
+  IN OUT EMBEDDED_GPIO        **GpioProtocol
+  )
+{
+  EFI_DEVICE_PATH     *DevicePath;
+  EFI_HANDLE          *HandleBuffer;
+  EFI_STATUS           Status;
+  UINTN                HandleCount;
+  UINTN                Index;
+
+  /* Locate Handles of all EMBEDDED_GPIO producers */
+  Status = gBS->LocateHandleBuffer (ByProtocol,
+                  &gEmbeddedGpioProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Unable to locate handles\n", __FUNCTION__));
+    return Status;
+  }
+
+  /* Iterate over all protocol producers */
+  for (Index = 0; Index < HandleCount; Index++) {
+    /* Open device path protocol installed on each handle */
+    Status = gBS->OpenProtocol (HandleBuffer[Index],
+                    &gEfiDevicePathProtocolGuid,
+                    (VOID **)&DevicePath,
+                    gImageHandle,
+                    NULL,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: Unable to find DevicePath\n", __FUNCTION__));
+      continue;
+    }
+
+    /*
+     * Check if the driver type matches the requested value.
+     * In case of the success open the GPIO protocol and return.
+     * If there is no match, repeat procedure with the next handle.
+     */
+    Status = MvGpioFindMatchingDriver (GpioDriverType,
+               HandleBuffer[Index],
+               DevicePath,
+               GpioProtocol);
+    if (Status == EFI_NOT_FOUND) {
+      continue;
+    } else if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR,
+        "%a: Unable to open GPIO protocol\n",
+        __FUNCTION__));
+    }
+
+    gBS->FreePool (HandleBuffer);
+
+    return Status;
+  }
+
+  /* No matching GPIO protocol producer was found */
+  gBS->FreePool (HandleBuffer);
+
+  return EFI_NOT_FOUND;
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 04/12] SolidRun/Armada80x0McBin: Extend board description library with GPIO
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
                   ` (2 preceding siblings ...)
  2019-01-17 11:15 ` [platforms: PATCH v3 03/12] Marvell/Library: Introduce MvGpioLib class Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:15 ` [platforms: PATCH v3 05/12] Marvell/Armada70x0Db: " Marcin Wojtas
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

This patch implements ArmadaBoarDescLib library for
Armada80x0McBin comunity board and introduces ArmadaBoardGpioGet
routine with per-board GPIO expander description.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.inf |  1 +
 Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.c   | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.inf b/Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.inf
index 63a4f66..43e4b9e 100644
--- a/Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.inf
+++ b/Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.inf
@@ -25,6 +25,7 @@
   Armada80x0McBinBoardDescLib.c
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Silicon/Marvell/Marvell.dec
diff --git a/Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.c b/Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.c
index d52adfc..32596ad 100644
--- a/Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.c
+++ b/Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.c
@@ -22,6 +22,23 @@
 #include <Library/UefiBootServicesTableLib.h>
 
 //
+// GPIO Expander
+//
+EFI_STATUS
+EFIAPI
+ArmadaBoardGpioExpanderGet (
+  IN OUT MV_GPIO_EXPANDER **GpioExpanders,
+  IN OUT UINTN             *GpioExpanderCount
+  )
+{
+  /* No GPIO expanders on board */
+  *GpioExpanders = NULL;
+  *GpioExpanderCount = 0;
+
+  return EFI_SUCCESS;
+}
+
+//
 // Order of devices in SdMmcDescTemplate has to be in par with ArmadaSoCDescLib
 //
 STATIC
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 05/12] Marvell/Armada70x0Db: Extend board description library with GPIO
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
                   ` (3 preceding siblings ...)
  2019-01-17 11:15 ` [platforms: PATCH v3 04/12] SolidRun/Armada80x0McBin: Extend board description library with GPIO Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:34   ` Leif Lindholm
  2019-01-17 11:15 ` [platforms: PATCH v3 06/12] Marvell/Armada80x0Db: " Marcin Wojtas
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

This patch implements ArmadaBoarDescLib library for
Armada70x0Db comunity board and introduces ArmadaBoardGpioGet
routine with per-board GPIO expander description.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
 Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c | 24 ++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c b/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c
index 48c68e4..f0133ec 100644
--- a/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c
+++ b/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c
@@ -19,9 +19,33 @@
 #include <Library/DebugLib.h>
 #include <Library/IoLib.h>
 #include <Library/MemoryAllocationLib.h>
+#include <Library/MvGpioLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 
 //
+// GPIO Expander
+//
+STATIC MV_GPIO_EXPANDER mGpioExpander = {
+  PCA9555_ID,
+  0x21,
+  0x0,
+};
+
+
+EFI_STATUS
+EFIAPI
+ArmadaBoardGpioExpanderGet (
+  IN OUT MV_GPIO_EXPANDER **GpioExpanders,
+  IN OUT UINTN             *GpioExpanderCount
+  )
+{
+  *GpioExpanderCount = 1;
+  *GpioExpanders = &mGpioExpander;
+
+  return EFI_SUCCESS;
+}
+
+//
 // Order of devices in SdMmcDescTemplate has to be in par with ArmadaSoCDescLib
 //
 STATIC
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 06/12] Marvell/Armada80x0Db: Extend board description library with GPIO
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
                   ` (4 preceding siblings ...)
  2019-01-17 11:15 ` [platforms: PATCH v3 05/12] Marvell/Armada70x0Db: " Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:34   ` Leif Lindholm
  2019-01-17 11:15 ` [platforms: PATCH v3 07/12] Marvell/Drivers: MvBoardDesc: Extend protocol with GPIO support Marcin Wojtas
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

This patch implements ArmadaBoarDescLib library for
Armada80x0Db board and introduces ArmadaBoardGpioGet
routine with per-board GPIO expander description.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
 Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c | 30 ++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c b/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c
index feb69ad..61b6202 100644
--- a/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c
+++ b/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c
@@ -19,9 +19,39 @@
 #include <Library/DebugLib.h>
 #include <Library/IoLib.h>
 #include <Library/MemoryAllocationLib.h>
+#include <Library/MvGpioLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 
 //
+// GPIO Expanders
+//
+STATIC MV_GPIO_EXPANDER mGpioExpanders[] = {
+  {
+    PCA9555_ID,
+    0x21,
+    0x0,
+  },
+  {
+    PCA9555_ID,
+    0x25,
+    0x0,
+  },
+};
+
+EFI_STATUS
+EFIAPI
+ArmadaBoardGpioExpanderGet (
+  IN OUT MV_GPIO_EXPANDER **GpioExpanders,
+  IN OUT UINTN             *GpioExpanderCount
+  )
+{
+  *GpioExpanderCount = ARRAY_SIZE (mGpioExpanders);
+  *GpioExpanders = mGpioExpanders;
+
+  return EFI_SUCCESS;
+}
+
+//
 // Order of devices in SdMmcDescTemplate has to be in par with ArmadaSoCDescLib
 //
 STATIC
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 07/12] Marvell/Drivers: MvBoardDesc: Extend protocol with GPIO support
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
                   ` (5 preceding siblings ...)
  2019-01-17 11:15 ` [platforms: PATCH v3 06/12] Marvell/Armada80x0Db: " Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:50   ` Leif Lindholm
  2019-01-17 11:15 ` [platforms: PATCH v3 08/12] Marvell/Drivers: MvGpioDxe: Introduce platform GPIO driver Marcin Wojtas
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

Introduce new callback that can provide information
about GPIO SoC controllers, as well as on-board
I2C IO expanders. According ArmadaSoCDescLib
ArmadaBoardDescLib routines are used for
obtaining required data.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
 Silicon/Marvell/Include/Protocol/BoardDesc.h       |  8 ++++
 Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c | 50 ++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/Silicon/Marvell/Include/Protocol/BoardDesc.h b/Silicon/Marvell/Include/Protocol/BoardDesc.h
index 1d57a16..02905ea 100644
--- a/Silicon/Marvell/Include/Protocol/BoardDesc.h
+++ b/Silicon/Marvell/Include/Protocol/BoardDesc.h
@@ -50,6 +50,13 @@ EFI_STATUS
 
 typedef
 EFI_STATUS
+(EFIAPI *MV_BOARD_GPIO_DESCRIPTION_GET) (
+  IN MARVELL_BOARD_DESC_PROTOCOL    *This,
+  IN OUT MV_BOARD_GPIO_DESCRIPTION **GpioDescription
+  );
+
+typedef
+EFI_STATUS
 (EFIAPI *MV_BOARD_DESC_I2C_GET) (
   IN MARVELL_BOARD_DESC_PROTOCOL  *This,
   IN OUT MV_BOARD_I2C_DESC       **I2cDesc
@@ -113,6 +120,7 @@ struct _MARVELL_BOARD_DESC_PROTOCOL {
   MV_BOARD_DESC_UTMI_GET         BoardDescUtmiGet;
   MV_BOARD_DESC_XHCI_GET         BoardDescXhciGet;
   MV_BOARD_DESC_FREE             BoardDescFree;
+  MV_BOARD_GPIO_DESCRIPTION_GET  GpioDescriptionGet;
 };
 
 #endif // __MARVELL_BOARD_DESC_PROTOCOL_H__
diff --git a/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c b/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c
index f71bfc4..973c362 100644
--- a/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c
+++ b/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c
@@ -35,6 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 MV_BOARD_DESC *mBoardDescInstance;
 
+STATIC MV_BOARD_GPIO_DESCRIPTION *mGpioDescription;
+
 STATIC
 EFI_STATUS
 MvBoardDescComPhyGet (
@@ -100,6 +102,53 @@ MvBoardDescComPhyGet (
 
 STATIC
 EFI_STATUS
+MvBoardGpioDescriptionGet (
+  IN MARVELL_BOARD_DESC_PROTOCOL    *This,
+  IN OUT MV_BOARD_GPIO_DESCRIPTION **GpioDescription
+  )
+{
+  UINTN SoCGpioCount, GpioExpanderCount;
+  MV_GPIO_EXPANDER *GpioExpanders;
+  GPIO_CONTROLLER *SoCGpio;
+  EFI_STATUS Status;
+
+  /* Use existing structure if already created. */
+  if (mGpioDescription != NULL) {
+    *GpioDescription = mGpioDescription;
+    return EFI_SUCCESS;
+  }
+
+  /* Get SoC data about all available GPIO controllers. */
+  Status = ArmadaSoCGpioGet (&SoCGpio, &SoCGpioCount);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  /* Get per-board information about all available GPIO expanders. */
+  Status = ArmadaBoardGpioExpanderGet (&GpioExpanders, &GpioExpanderCount);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  /* Allocate and fill board description. */
+  mGpioDescription = AllocateZeroPool (sizeof (MV_BOARD_GPIO_DESCRIPTION));
+  if (mGpioDescription == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Cannot allocate memory\n", __FUNCTION__));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mGpioDescription->SoCGpio = SoCGpio;
+  mGpioDescription->GpioDeviceCount = SoCGpioCount;
+  mGpioDescription->GpioExpanders = GpioExpanders;
+  mGpioDescription->GpioExpanderCount = GpioExpanderCount;
+
+  *GpioDescription = mGpioDescription;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
 MvBoardDescI2cGet (
   IN MARVELL_BOARD_DESC_PROTOCOL  *This,
   IN OUT MV_BOARD_I2C_DESC       **I2cDesc
@@ -571,6 +620,7 @@ MvBoardDescInitProtocol (
   BoardDescProtocol->BoardDescUtmiGet = MvBoardDescUtmiGet;
   BoardDescProtocol->BoardDescXhciGet = MvBoardDescXhciGet;
   BoardDescProtocol->BoardDescFree = MvBoardDescFree;
+  BoardDescProtocol->GpioDescriptionGet = MvBoardGpioDescriptionGet;
 
   return EFI_SUCCESS;
 }
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 08/12] Marvell/Drivers: MvGpioDxe: Introduce platform GPIO driver
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
                   ` (6 preceding siblings ...)
  2019-01-17 11:15 ` [platforms: PATCH v3 07/12] Marvell/Drivers: MvBoardDesc: Extend protocol with GPIO support Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:52   ` Leif Lindholm
  2019-01-17 11:15 ` [platforms: PATCH v3 09/12] Marvell/Drivers: I2c: Use common header for macros Marcin Wojtas
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

Marvell Armada 7k/8k SoCs comprise integrated GPIO controllers,
one in AP806 and two in each south bridge hardware blocks.

This patch introduces support for them. The new driver implements
a generic EMBEDDED_GPIO protocol.

In order to ease description of used GPIO pins and controllers
of the Armada 7k8k platforms, add a common enum type.

Based on original work of Jing Hua <jinghua@marvell.com>.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf |  44 +++
 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h   |  49 +++
 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c   | 353 ++++++++++++++++++++
 3 files changed, 446 insertions(+)
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c

diff --git a/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
new file mode 100644
index 0000000..5ff9130
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
@@ -0,0 +1,44 @@
+## @file
+#
+#  Copyright (c) 2017, Marvell International Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+#  IMPLIED.
+#
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = MvGpioDxe
+  FILE_GUID                      = 706eb761-b3b5-4f41-8558-5fd9217c0079
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = MvGpioEntryPoint
+
+[Sources]
+  MvGpioDxe.c
+  MvGpioDxe.h
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+  ArmadaSoCDescLib
+  DebugLib
+  MemoryAllocationLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Protocols]
+  gEmbeddedGpioProtocolGuid
+  gMarvellBoardDescProtocolGuid
+
+[Depex]
+  TRUE
diff --git a/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h
new file mode 100644
index 0000000..6e56ec1
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h
@@ -0,0 +1,49 @@
+/**
+*
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+#ifndef __MV_GPIO_H__
+#define __MV_GPIO_H__
+
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/MvGpioLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/BoardDesc.h>
+
+#include <Uefi/UefiBaseType.h>
+
+#define MV_GPIO_SIGNATURE        SIGNATURE_64 ('M', 'V','_','G', 'P', 'I','O',' ')
+
+// Marvell MV_GPIO Controller Registers
+#define MV_GPIO_DATA_OUT_REG     (0x0)
+#define MV_GPIO_OUT_EN_REG       (0x4)
+#define MV_GPIO_BLINK_EN_REG     (0x8)
+#define MV_GPIO_DATA_IN_POL_REG  (0xc)
+#define MV_GPIO_DATA_IN_REG      (0x10)
+
+typedef struct {
+  EMBEDDED_GPIO     GpioProtocol;
+  GPIO_CONTROLLER  *SoCGpio;
+  UINTN             GpioDeviceCount;
+  UINTN             Signature;
+  EFI_HANDLE        Handle;
+} MV_GPIO;
+
+#endif // __MV_GPIO_H__
diff --git a/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c
new file mode 100644
index 0000000..1d37ecc
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c
@@ -0,0 +1,353 @@
+/**
+*
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "MvGpioDxe.h"
+
+STATIC MV_GPIO *mGpioInstance;
+
+STATIC MV_GPIO_DEVICE_PATH mDevicePathTemplate = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH) +
+                 sizeof (MV_GPIO_DRIVER_TYPE)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH) +
+                 sizeof (MV_GPIO_DRIVER_TYPE)) >> 8),
+      },
+    },
+    EFI_CALLER_ID_GUID
+  },
+  MV_GPIO_DRIVER_TYPE_SOC_CONTROLLER,
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      sizeof(EFI_DEVICE_PATH_PROTOCOL),
+      0
+    }
+  }
+};
+
+#if !defined(MDEPKG_NDEBUG)
+/**
+
+Routine Description:
+
+  Verifies if controller index / GPIO pin values
+  are within proper boundaries.
+
+Arguments:
+
+  ControllerIndex - index of controller
+  GpioPin - which pin to read
+
+Returns:
+
+  EFI_SUCCESS           - GPIO pin / controller index are proper
+  EFI_INVALID_PARAMETER - GPIO pin / controller index is out of range
+**/
+STATIC
+EFI_STATUS
+MvGpioValidate (
+  IN UINTN ControllerIndex,
+  IN UINTN GpioPin
+  )
+{
+  if (ControllerIndex >= mGpioInstance->GpioDeviceCount) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: Invalid GPIO ControllerIndex: %d\n",
+      __FUNCTION__,
+      ControllerIndex));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (GpioPin >= mGpioInstance->SoCGpio[ControllerIndex].InternalGpioCount) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: GPIO pin #%d not available in Controller#%d\n",
+      __FUNCTION__,
+      GpioPin,
+      ControllerIndex));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+#endif
+
+/**
+
+Routine Description:
+
+  Gets the mode (function) of a GPIO pin
+
+Arguments:
+
+  This  - pointer to protocol
+  Gpio  - which pin
+  Mode  - pointer to output mode value
+
+Returns:
+
+  EFI_SUCCESS           - mode value retrieved
+  EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range
+
+**/
+STATIC
+EFI_STATUS
+MvGpioGetMode (
+  IN  EMBEDDED_GPIO       *This,
+  IN  EMBEDDED_GPIO_PIN    Gpio,
+  OUT EMBEDDED_GPIO_MODE  *Mode
+  )
+{
+  UINTN ControllerIndex;
+  UINTN BaseAddress;
+  UINTN GpioPin;
+
+  GpioPin = GPIO_PIN (Gpio);
+  ControllerIndex = GPIO_PORT (Gpio);
+
+  ASSERT_EFI_ERROR (MvGpioValidate (ControllerIndex, GpioPin));
+
+  BaseAddress = mGpioInstance->SoCGpio[ControllerIndex].RegisterBase;
+
+  if (MmioRead32 (BaseAddress + MV_GPIO_OUT_EN_REG) & (1 << GpioPin)) {
+    *Mode = GPIO_MODE_INPUT;
+  } else {
+    if (MmioRead32 (BaseAddress + MV_GPIO_DATA_IN_REG) & (1 << GpioPin)) {
+      *Mode = GPIO_MODE_OUTPUT_1;
+    } else {
+      *Mode = GPIO_MODE_OUTPUT_0;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+Routine Description:
+
+  Gets the state of a GPIO pin
+
+Arguments:
+
+  This  - pointer to protocol
+  Gpio  - which pin to read
+  Value - state of the pin
+
+Returns:
+
+  EFI_SUCCESS           - GPIO state returned in Value
+  EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range
+**/
+STATIC
+EFI_STATUS
+MvGpioGet (
+  IN  EMBEDDED_GPIO      *This,
+  IN  EMBEDDED_GPIO_PIN   Gpio,
+  OUT UINTN              *Value
+  )
+{
+  UINTN ControllerIndex;
+  UINTN BaseAddress;
+  UINTN GpioPin;
+
+  GpioPin = GPIO_PIN (Gpio);
+  ControllerIndex = GPIO_PORT (Gpio);
+
+  ASSERT_EFI_ERROR (MvGpioValidate (ControllerIndex, GpioPin));
+
+  BaseAddress = mGpioInstance->SoCGpio[ControllerIndex].RegisterBase;
+
+  if (MmioRead32 (BaseAddress + MV_GPIO_DATA_IN_REG) & (1 << GpioPin)) {
+    *Value = 1;
+  } else {
+    *Value = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+Routine Description:
+
+  Sets the state of a GPIO pin
+
+Arguments:
+
+  This  - pointer to protocol
+  Gpio  - which pin to modify
+  Mode  - mode to set
+
+Returns:
+
+  EFI_SUCCESS           - GPIO set as requested
+  EFI_UNSUPPORTED       - Mode is not supported
+  EFI_INVALID_PARAMETER - Gpio pin is out of range
+**/
+STATIC
+EFI_STATUS
+MvGpioSet (
+  IN EMBEDDED_GPIO       *This,
+  IN EMBEDDED_GPIO_PIN    Gpio,
+  IN EMBEDDED_GPIO_MODE   Mode
+  )
+{
+  UINTN ControllerIndex;
+  UINTN BaseAddress;
+  UINTN GpioPin;
+
+  GpioPin = GPIO_PIN (Gpio);
+  ControllerIndex = GPIO_PORT (Gpio);
+
+  ASSERT_EFI_ERROR (MvGpioValidate (ControllerIndex, GpioPin));
+
+  BaseAddress = mGpioInstance->SoCGpio[ControllerIndex].RegisterBase;
+
+  switch (Mode) {
+  case GPIO_MODE_OUTPUT_0:
+    MmioAnd32 (BaseAddress + MV_GPIO_DATA_OUT_REG, ~(1 << GpioPin));
+    MmioAnd32 (BaseAddress + MV_GPIO_OUT_EN_REG, ~(1 << GpioPin));
+    break;
+
+  case GPIO_MODE_OUTPUT_1:
+    MmioOr32 (BaseAddress + MV_GPIO_DATA_OUT_REG, (1 << GpioPin));
+    MmioAnd32 (BaseAddress + MV_GPIO_OUT_EN_REG, ~(1 << GpioPin));
+    break;
+
+  case GPIO_MODE_INPUT:
+    MmioOr32 (BaseAddress + MV_GPIO_OUT_EN_REG, (1 << GpioPin));
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+Routine Description:
+
+  Sets the pull-up / pull-down resistor of a GPIO pin
+
+Arguments:
+
+  This  - pointer to protocol
+  Gpio  - which pin
+  Direction - pull-up, pull-down, or none
+
+Returns:
+
+  EFI_UNSUPPORTED - Can not perform the requested operation
+
+**/
+EFI_STATUS
+EFIAPI
+MvGpioSetPull (
+  IN  EMBEDDED_GPIO       *This,
+  IN  EMBEDDED_GPIO_PIN   Gpio,
+  IN  EMBEDDED_GPIO_PULL  Direction
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+VOID
+MvGpioInitProtocol (
+  IN EMBEDDED_GPIO *GpioProtocol
+  )
+{
+  GpioProtocol->Get     = MvGpioGet;
+  GpioProtocol->Set     = MvGpioSet;
+  GpioProtocol->GetMode = MvGpioGetMode;
+  GpioProtocol->SetPull = MvGpioSetPull;
+}
+
+EFI_STATUS
+EFIAPI
+MvGpioEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  MARVELL_BOARD_DESC_PROTOCOL *MvBoardProtocol;
+  MV_BOARD_GPIO_DESCRIPTION *GpioDescription;
+  MV_GPIO_DEVICE_PATH *GpioDevicePath;
+  EFI_STATUS Status;
+
+  GpioDevicePath = AllocateCopyPool (sizeof (MV_GPIO_DEVICE_PATH),
+                     &mDevicePathTemplate);
+  if (GpioDevicePath == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mGpioInstance = AllocateZeroPool (sizeof (MV_GPIO));
+  if (mGpioInstance == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrGpioInstanceAlloc;
+  }
+
+  /* Obtain list of available controllers */
+  Status = gBS->LocateProtocol (&gMarvellBoardDescProtocolGuid,
+                  NULL,
+                  (VOID **)&MvBoardProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: Cannot locate BoardDesc protocol\n",
+      __FUNCTION__));
+    goto ErrLocateBoardDesc;
+  }
+
+  Status = MvBoardProtocol->GpioDescriptionGet (MvBoardProtocol,
+             &GpioDescription);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: Cannot get GPIO board desc from BoardDesc protocol\n",
+      __FUNCTION__));
+    goto ErrLocateBoardDesc;
+  }
+
+  mGpioInstance->Signature = MV_GPIO_SIGNATURE;
+  mGpioInstance->GpioDeviceCount = GpioDescription->GpioDeviceCount;
+  mGpioInstance->SoCGpio = GpioDescription->SoCGpio;
+
+  MvGpioInitProtocol (&mGpioInstance->GpioProtocol);
+
+  Status = gBS->InstallMultipleProtocolInterfaces (&(mGpioInstance->Handle),
+                  &gEmbeddedGpioProtocolGuid,
+                  &(mGpioInstance->GpioProtocol),
+                  &gEfiDevicePathProtocolGuid,
+                  (EFI_DEVICE_PATH_PROTOCOL *)GpioDevicePath,
+                  NULL);
+  if (EFI_ERROR (Status)) {
+    goto ErrLocateBoardDesc;
+  }
+
+  return EFI_SUCCESS;
+
+ErrLocateBoardDesc:
+  gBS->FreePool (mGpioInstance);
+
+ErrGpioInstanceAlloc:
+  gBS->FreePool (GpioDevicePath);
+
+  return Status;
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 09/12] Marvell/Drivers: I2c: Use common header for macros
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
                   ` (7 preceding siblings ...)
  2019-01-17 11:15 ` [platforms: PATCH v3 08/12] Marvell/Drivers: MvGpioDxe: Introduce platform GPIO driver Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:15 ` [platforms: PATCH v3 10/12] Marvell/Drivers: MvPca95xxDxe: Introduce GPIO expander driver Marcin Wojtas
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

Hitherto I2c solution used same macros, defined in multiple
places. Move them to a new common header.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.h | 10 -------
 Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.h       | 17 ++---------
 Silicon/Marvell/Include/Protocol/MvI2c.h              | 31 ++++++++++++++++++++
 Silicon/Marvell/Applications/EepromCmd/EepromCmd.c    |  5 +---
 Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.c |  3 +-
 Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.c       |  4 +--
 6 files changed, 37 insertions(+), 33 deletions(-)
 create mode 100644 Silicon/Marvell/Include/Protocol/MvI2c.h

diff --git a/Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.h b/Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.h
index b1af645..c32ee48 100644
--- a/Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.h
+++ b/Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.h
@@ -41,16 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #define MAX_BUFFER_LENGTH 64
 
-/*
- * I2C_FLAG_NORESTART is not part of PI spec, it allows to continue
- * transmission without repeated start operation.
- * FIXME: This flag is also defined in Drivers/I2c/MvI2cDxe/MvI2cDxe.h
- * and it's important to have both version synced. This solution is
- * temporary and shared flag should be used by both files.
- * Situation is analogous with I2C_GUID, which also should be common, but is
- * for now defined same way in two header files.
- */
-#define I2C_FLAG_NORESTART 0x00000002
 #define I2C_GUID \
   { \
   0xadc1901b, 0xb83c, 0x4831, { 0x8f, 0x59, 0x70, 0x89, 0x8f, 0x26, 0x57, 0x1e } \
diff --git a/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.h b/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.h
index 3c9beaf..6850c34 100644
--- a/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.h
+++ b/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.h
@@ -32,8 +32,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 *******************************************************************************/
 
-#ifndef __MV_I2C_H__
-#define __MV_I2C_H__
+#ifndef __MV_I2C_DXE_H__
+#define __MV_I2C_DXE_H__
 
 #include <Uefi.h>
 
@@ -75,17 +75,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define I2C_FAST           0x2
 #define I2C_FASTEST        0x3
 
-/*
- * I2C_FLAG_NORESTART is not part of PI spec, it allows to continue
- * transmission without repeated start operation.
- * FIXME: This flag is also defined in
- * Platforms/Marvell/Include/Protocol/Eeprom.h and it's important to have both
- * version synced. This solution is temporary and shared flag should be used by
- * both files.
- * Situation is analogous with I2C_GUID, which also should be common, but is
- * for now defined same way in two header files.
- */
-#define I2C_FLAG_NORESTART 0x00000002
 #define I2C_GUID \
   { \
   0xadc1901b, 0xb83c, 0x4831, { 0x8f, 0x59, 0x70, 0x89, 0x8f, 0x26, 0x57, 0x1e } \
@@ -266,4 +255,4 @@ MvI2cEnableConf (
   IN EFI_STATUS                                          *I2cStatus OPTIONAL
   );
 
-#endif // __MV_I2C_H__
+#endif // __MV_I2C_DXE_H__
diff --git a/Silicon/Marvell/Include/Protocol/MvI2c.h b/Silicon/Marvell/Include/Protocol/MvI2c.h
new file mode 100644
index 0000000..d8e644e
--- /dev/null
+++ b/Silicon/Marvell/Include/Protocol/MvI2c.h
@@ -0,0 +1,31 @@
+/**
+*
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+#ifndef __MV_I2C_H__
+#define __MV_I2C_H__
+
+/*
+ * I2C_FLAG_NORESTART is not part of PI spec, it allows to continue
+ * transmission without repeated start operation.
+ */
+#define I2C_FLAG_NORESTART             0x00000002
+
+/*
+ * Helper macros for maintaining multiple I2C buses
+ * and devices defined via EFI_I2C_DEVICE.
+ */
+#define I2C_DEVICE_ADDRESS(Index)      ((Index) & MAX_UINT16)
+#define I2C_DEVICE_BUS(Index)          ((Index) >> 16)
+#define I2C_DEVICE_INDEX(Bus, Address) (((Address) & MAX_UINT16) | (Bus) << 16)
+
+#endif
diff --git a/Silicon/Marvell/Applications/EepromCmd/EepromCmd.c b/Silicon/Marvell/Applications/EepromCmd/EepromCmd.c
index dc3c95f..712aba9 100644
--- a/Silicon/Marvell/Applications/EepromCmd/EepromCmd.c
+++ b/Silicon/Marvell/Applications/EepromCmd/EepromCmd.c
@@ -51,10 +51,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <Library/UefiBootServicesTableLib.h>
 
 #include <Protocol/Eeprom.h>
-
-#define I2C_DEVICE_INDEX(bus, address) (((address) & 0xffff) | (bus) << 16)
-#define I2C_DEVICE_ADDRESS(index) ((index) & 0xffff)
-#define I2C_DEVICE_BUS(index) ((index) >> 16)
+#include <Protocol/MvI2c.h>
 
 CONST CHAR16 ShellEepromFileName[] = L"ShellCommand";
 EFI_HANDLE ShellEepromHiiHandle = NULL;
diff --git a/Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.c b/Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.c
index 9d2f650..90d0d1e 100644
--- a/Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.c
+++ b/Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.c
@@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <Protocol/DriverBinding.h>
 #include <Protocol/I2cIo.h>
 #include <Protocol/Eeprom.h>
+#include <Protocol/MvI2c.h>
 
 #include <Library/BaseLib.h>
 #include <Library/BaseMemoryLib.h>
@@ -49,8 +50,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "MvEepromDxe.h"
 
-#define I2C_DEVICE_INDEX(bus, address) (((address) & 0xffff) | (bus) << 16)
-
 STATIC CONST EFI_GUID I2cGuid = I2C_GUID;
 
 EFI_DRIVER_BINDING_PROTOCOL gDriverBindingProtocol = {
diff --git a/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.c b/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.c
index 9ec4929..582e2b9 100755
--- a/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.c
+++ b/Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.c
@@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <Protocol/I2cEnumerate.h>
 #include <Protocol/I2cBusConfigurationManagement.h>
 #include <Protocol/DevicePath.h>
+#include <Protocol/MvI2c.h>
 
 #include <Library/BaseLib.h>
 #include <Library/IoLib.h>
@@ -628,9 +629,6 @@ MvI2cStartRequest (
 
 STATIC CONST EFI_GUID DevGuid = I2C_GUID;
 
-#define I2C_DEVICE_INDEX(bus, address) (((address) & 0xffff) | (bus) << 16)
-#define I2C_DEVICE_ADDRESS(index) ((index) & 0xffff)
-
 STATIC
 EFI_STATUS
 MvI2cAllocDevice (
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 10/12] Marvell/Drivers: MvPca95xxDxe: Introduce GPIO expander driver
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
                   ` (8 preceding siblings ...)
  2019-01-17 11:15 ` [platforms: PATCH v3 09/12] Marvell/Drivers: I2c: Use common header for macros Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:55   ` Leif Lindholm
  2019-01-17 11:15 ` [platforms: PATCH v3 11/12] Marvell/Armada7k8k: Enable GPIO drivers compilation Marcin Wojtas
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

Marvell Armada 7k/8k-based platforms may use Pca95xx to extend
amount of the GPIO pins.

This patch introduces support for them. The new driver implements
a generic EMBEDDED_GPIO protocol.

In order to ease description of used PCA9XXX controllers
add a common enum type. It can be used e.g. in the board description
library to specify the expander model on a board (instead of passing
a raw number). Update relevant libraries.

Driver is based on initial work done by Allen Yan <yanwei@marvell.com>.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf |  45 ++
 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h   |  65 ++
 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c   | 645 ++++++++++++++++++++
 3 files changed, 755 insertions(+)
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h
 create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c

diff --git a/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
new file mode 100644
index 0000000..3b1ab4e
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
@@ -0,0 +1,45 @@
+## @file
+#
+#  Copyright (c) 2017, Marvell International Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+#  IMPLIED.
+#
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = MvPca95xxDxe
+  FILE_GUID                      = f0e405eb-8407-43b9-88e6-2f7d70715c72
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = MvPca95xxEntryPoint
+
+[Sources]
+  MvPca95xxDxe.c
+  MvPca95xxDxe.h
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+  DebugLib
+  MemoryAllocationLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Protocols]
+  gEfiDriverBindingProtocolGuid
+  gEfiI2cIoProtocolGuid
+  gEmbeddedGpioProtocolGuid
+  gMarvellBoardDescProtocolGuid
+
+[Depex]
+  TRUE
diff --git a/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h
new file mode 100644
index 0000000..29eb123
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h
@@ -0,0 +1,65 @@
+/**
+*
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+#ifndef __MV_PCA953X_H__
+#define __MV_PCA953X_H__
+
+#include <Library/ArmadaBoardDescLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/MvGpioLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/BoardDesc.h>
+#include <Protocol/MvI2c.h>
+
+#include <Uefi/UefiBaseType.h>
+
+#define PCA95XX_GPIO_SIGNATURE   SIGNATURE_32 ('I', 'O', 'E', 'X')
+
+#define PCA95XX_INPUT_REG        0x0
+#define PCA95XX_OUTPUT_REG       0x2
+#define PCA95XX_DIRECTION_REG    0x6
+
+#define PCA95XX_BANK_SIZE        8
+#define PCA95XX_OPERATION_COUNT  2
+#define PCA95XX_OPERATION_LENGTH 1
+
+typedef enum {
+  PCA9505_PIN_COUNT = 40,
+  PCA9534_PIN_COUNT = 8,
+  PCA9535_PIN_COUNT = 16,
+  PCA9536_PIN_COUNT = 4,
+  PCA9537_PIN_COUNT = 4,
+  PCA9538_PIN_COUNT = 8,
+  PCA9539_PIN_COUNT = 16,
+  PCA9554_PIN_COUNT = 8,
+  PCA9555_PIN_COUNT = 16,
+  PCA9556_PIN_COUNT = 16,
+  PCA9557_PIN_COUNT = 16,
+} PCA95XX_PIN_COUNT;
+
+typedef struct {
+  EMBEDDED_GPIO      GpioProtocol;
+  MV_GPIO_EXPANDER  *GpioExpanders;
+  UINTN              GpioExpanderCount;
+  UINTN              Signature;
+  EFI_HANDLE         ControllerHandle;
+} PCA95XX;
+
+#endif
diff --git a/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c
new file mode 100644
index 0000000..8e7ea77
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c
@@ -0,0 +1,645 @@
+/**
+*
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Protocol/I2cIo.h>
+
+#include <Pi/PiI2c.h>
+
+#include "MvPca95xxDxe.h"
+
+STATIC PCA95XX *mPca95xxInstance;
+
+STATIC MV_GPIO_DEVICE_PATH mDevicePathTemplate = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH) +
+                 sizeof (MV_GPIO_DRIVER_TYPE)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH) +
+                 sizeof (MV_GPIO_DRIVER_TYPE)) >> 8),
+      },
+    },
+    EFI_CALLER_ID_GUID
+  },
+  MV_GPIO_DRIVER_TYPE_PCA95XX,
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      sizeof(EFI_DEVICE_PATH_PROTOCOL),
+      0
+    }
+  }
+};
+
+STATIC PCA95XX_PIN_COUNT mPca95xxPinCount[PCA95XX_MAX_ID] = {
+  PCA9505_PIN_COUNT,
+  PCA9534_PIN_COUNT,
+  PCA9535_PIN_COUNT,
+  PCA9536_PIN_COUNT,
+  PCA9537_PIN_COUNT,
+  PCA9538_PIN_COUNT,
+  PCA9539_PIN_COUNT,
+  PCA9554_PIN_COUNT,
+  PCA9555_PIN_COUNT,
+  PCA9556_PIN_COUNT,
+  PCA9557_PIN_COUNT,
+};
+
+#if !defined(MDEPKG_NDEBUG)
+/**
+
+Routine Description:
+
+  Verifies if controller index / GPIO pin values
+  are within proper boundaries.
+
+Arguments:
+
+  ControllerIndex - index of controller
+  GpioPin - which pin to read
+
+Returns:
+
+  EFI_SUCCESS           - GPIO pin / controller index are proper
+  EFI_INVALID_PARAMETER - GPIO pin / controller index is out of range
+**/
+STATIC
+EFI_STATUS
+MvPca95xxValidate (
+  IN UINTN ControllerIndex,
+  IN UINTN GpioPin
+  )
+{
+  UINTN ControllerId;
+
+  if (ControllerIndex >= mPca95xxInstance->GpioExpanderCount) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: Invalid GPIO ControllerIndex: %d\n",
+      __FUNCTION__,
+      ControllerIndex));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ControllerId = mPca95xxInstance->GpioExpanders[ControllerIndex].ChipId;
+
+  if (GpioPin >= mPca95xxPinCount[ControllerId]) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: GPIO pin #%d not available in Controller#%d\n",
+      __FUNCTION__,
+      GpioPin,
+      ControllerIndex));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+#endif
+
+EFI_STATUS
+EFIAPI
+MvPca95xxGetI2c (
+  IN     UINTN                 ControllerIndex,
+  IN OUT EFI_I2C_IO_PROTOCOL **I2cIo
+  )
+{
+  UINTN        I2cBus, I2cAddress;
+  UINTN        HandleCount, Index;
+  EFI_HANDLE  *HandleBuffer;
+  EFI_STATUS   Status;
+
+  I2cBus = mPca95xxInstance->GpioExpanders[ControllerIndex].I2cBus;
+  I2cAddress = mPca95xxInstance->GpioExpanders[ControllerIndex].I2cAddress;
+
+  /* Locate Handles of all EfiI2cIoProtocol producers */
+  Status = gBS->LocateHandleBuffer (ByProtocol,
+                  &gEfiI2cIoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Unable to locate handles\n", __FUNCTION__));
+    return Status;
+  }
+
+  /* Iterate over all protocol producers and pick one upon DeviceIndex match */
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->OpenProtocol (HandleBuffer[Index],
+                    &gEfiI2cIoProtocolGuid,
+                    (VOID **)I2cIo,
+                    gImageHandle,
+                    NULL,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: Unable to open protocol\n", __FUNCTION__));
+      gBS->FreePool (HandleBuffer);
+      return Status;
+    }
+    if ((*I2cIo)->DeviceIndex == I2C_DEVICE_INDEX (I2cBus, I2cAddress)) {
+      gBS->FreePool (HandleBuffer);
+      return EFI_SUCCESS;
+    }
+  }
+
+  gBS->FreePool (HandleBuffer);
+
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+EFIAPI
+MvPca95xxI2cTransfer (
+  IN EFI_I2C_IO_PROTOCOL *I2cIo,
+  IN UINT8                Address,
+  IN UINT8               *Buffer,
+  IN UINT32               Flag
+  )
+{
+  EFI_I2C_REQUEST_PACKET *RequestPacket;
+  UINTN RequestPacketSize;
+  UINT8 AddressBuffer;
+  EFI_STATUS Status;
+
+  RequestPacketSize = sizeof (UINTN) +
+                      sizeof (EFI_I2C_OPERATION) * PCA95XX_OPERATION_COUNT;
+  RequestPacket = AllocateZeroPool (RequestPacketSize);
+  if (RequestPacket == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  /* Operations contain address and payload, consecutively. */
+  RequestPacket->OperationCount = PCA95XX_OPERATION_COUNT;
+  RequestPacket->Operation[0].LengthInBytes = PCA95XX_OPERATION_LENGTH;
+  RequestPacket->Operation[0].Buffer = &AddressBuffer;
+  RequestPacket->Operation[0].Buffer[0] = Address & MAX_UINT8;
+  RequestPacket->Operation[1].LengthInBytes = PCA95XX_OPERATION_LENGTH;
+  RequestPacket->Operation[1].Buffer = Buffer;
+  RequestPacket->Operation[1].Flags = Flag;
+
+  Status = I2cIo->QueueRequest (I2cIo, 0, NULL, RequestPacket, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: transmission error: 0x%d\n",
+      __FUNCTION__,
+      Status));
+  }
+
+  gBS->FreePool(RequestPacket);
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+MvPca95xxReadRegs (
+  IN  EFI_I2C_IO_PROTOCOL *I2cIo,
+  IN  UINT8                Reg,
+  OUT UINT8               *RegVal
+  )
+{
+  return MvPca95xxI2cTransfer (I2cIo, Reg, RegVal, I2C_FLAG_READ);
+}
+
+STATIC
+EFI_STATUS
+MvPca95xxWriteRegs (
+  IN  EFI_I2C_IO_PROTOCOL *I2cIo,
+  IN  UINTN                Reg,
+  IN  UINT8                RegVal
+  )
+{
+  return MvPca95xxI2cTransfer (I2cIo, Reg, &RegVal, I2C_FLAG_NORESTART);
+}
+
+STATIC
+EFI_STATUS
+MvPca95xxSetOutputValue (
+  IN UINTN               ControllerIndex,
+  IN UINTN               GpioPin,
+  IN EMBEDDED_GPIO_MODE  Mode
+  )
+{
+  EFI_I2C_IO_PROTOCOL *I2cIo;
+  EFI_STATUS Status;
+  UINT8 RegVal;
+  UINTN Bank;
+
+  Status = MvPca95xxGetI2c (ControllerIndex, &I2cIo);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: fail to get I2C protocol\n", __FUNCTION__));
+    return EFI_DEVICE_ERROR;
+  }
+
+  Bank = GpioPin / PCA95XX_BANK_SIZE;
+
+  Status = MvPca95xxReadRegs (I2cIo, PCA95XX_OUTPUT_REG + Bank, &RegVal);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: fail to read device register\n", __FUNCTION__));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (Mode == GPIO_MODE_OUTPUT_1) {
+    RegVal |= (1 << (GpioPin % PCA95XX_BANK_SIZE));
+  } else {
+    RegVal &= ~(1 << (GpioPin % PCA95XX_BANK_SIZE));
+  }
+
+  Status = MvPca95xxWriteRegs (I2cIo, PCA95XX_OUTPUT_REG + Bank, RegVal);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: fail to write device register\n", __FUNCTION__));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+MvPca95xxSetDirection (
+  IN UINTN              ControllerIndex,
+  IN UINTN              GpioPin,
+  IN EMBEDDED_GPIO_MODE Mode
+  )
+{
+  EFI_I2C_IO_PROTOCOL *I2cIo;
+  EFI_STATUS Status;
+  UINT8 RegVal;
+  UINTN Bank;
+
+  Status = MvPca95xxGetI2c (ControllerIndex, &I2cIo);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: fail to get I2C protocol\n", __FUNCTION__));
+    return Status;
+  }
+
+  Bank = GpioPin / PCA95XX_BANK_SIZE;
+
+  Status = MvPca95xxReadRegs (I2cIo, PCA95XX_DIRECTION_REG + Bank, &RegVal);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: fail to read device register\n", __FUNCTION__));
+    return Status;
+  }
+
+  if (Mode == GPIO_MODE_INPUT) {
+    RegVal |= (1 << (GpioPin % PCA95XX_BANK_SIZE));
+  } else {
+    RegVal &= ~(1 << (GpioPin % PCA95XX_BANK_SIZE));
+  }
+
+  Status = MvPca95xxWriteRegs (I2cIo, PCA95XX_DIRECTION_REG + Bank, RegVal);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: fail to write device register\n", __FUNCTION__));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+MvPca95xxReadMode (
+  IN  UINTN               ControllerIndex,
+  IN  UINTN               GpioPin,
+  OUT EMBEDDED_GPIO_MODE *Mode
+  )
+{
+  EFI_I2C_IO_PROTOCOL *I2cIo;
+  EFI_STATUS Status;
+  UINT8 RegVal;
+  UINTN Bank;
+
+  ASSERT_EFI_ERROR (MvPca95xxValidate (ControllerIndex, GpioPin));
+
+  Status = MvPca95xxGetI2c (ControllerIndex, &I2cIo);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: fail to get I2C protocol\n", __FUNCTION__));
+    return Status;
+  }
+
+  Bank = GpioPin / PCA95XX_BANK_SIZE;
+
+  Status = MvPca95xxReadRegs (I2cIo, PCA95XX_DIRECTION_REG + Bank, &RegVal);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: fail to read device register\n", __FUNCTION__));
+    return Status;
+  }
+
+  if (RegVal & (1 << (GpioPin % PCA95XX_BANK_SIZE))) {
+    *Mode = GPIO_MODE_INPUT;
+  } else {
+    Status = MvPca95xxReadRegs (I2cIo, PCA95XX_INPUT_REG + Bank, &RegVal);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: fail to read device register\n", __FUNCTION__));
+      return Status;
+    }
+
+    if (RegVal & (1 << (GpioPin % PCA95XX_BANK_SIZE))) {
+      *Mode = GPIO_MODE_OUTPUT_1;
+    } else {
+      *Mode = GPIO_MODE_OUTPUT_0;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+Routine Description:
+
+  Gets the mode (function) of a GPIO pin
+
+Arguments:
+
+  This  - pointer to protocol
+  Gpio  - which pin
+  Mode  - pointer to output mode value
+
+Returns:
+
+  EFI_SUCCESS           - mode value retrieved
+  EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range
+
+**/
+STATIC
+EFI_STATUS
+MvPca95xxGetMode (
+  IN  EMBEDDED_GPIO       *This,
+  IN  EMBEDDED_GPIO_PIN    Gpio,
+  OUT EMBEDDED_GPIO_MODE  *Mode
+  )
+{
+  EFI_STATUS Status;
+  UINTN ControllerIndex;
+  UINTN GpioPin;
+
+  GpioPin = GPIO_PIN (Gpio);
+  ControllerIndex = GPIO_PORT (Gpio);
+
+  ASSERT_EFI_ERROR (MvPca95xxValidate (ControllerIndex, GpioPin));
+
+  Status = MvPca95xxReadMode (ControllerIndex, GpioPin, Mode);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: fail to get pin %d of controller#%d mode\n",
+      __FUNCTION__,
+      GpioPin,
+      ControllerIndex));
+  }
+
+  return Status;
+}
+
+/**
+
+Routine Description:
+
+  Gets the state of a GPIO pin
+
+Arguments:
+
+  This  - pointer to protocol
+  Gpio  - which pin to read
+  Value - state of the pin
+
+Returns:
+
+  EFI_SUCCESS           - GPIO state returned in Value
+  EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range
+**/
+STATIC
+EFI_STATUS
+MvPca95xxGet (
+  IN  EMBEDDED_GPIO      *This,
+  IN  EMBEDDED_GPIO_PIN   Gpio,
+  OUT UINTN              *Value
+  )
+{
+  EFI_I2C_IO_PROTOCOL *I2cIo;
+  EFI_STATUS Status;
+  UINTN ControllerIndex;
+  UINTN GpioPin;
+  UINT8 RegVal;
+  UINTN Bank;
+
+  GpioPin = GPIO_PIN (Gpio);
+  ControllerIndex = GPIO_PORT (Gpio);
+
+  ASSERT_EFI_ERROR (MvPca95xxValidate (ControllerIndex, GpioPin));
+
+  Status = MvPca95xxGetI2c (ControllerIndex, &I2cIo);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: fail to get I2C protocol\n", __FUNCTION__));
+    return Status;
+  }
+
+  Bank = GpioPin / PCA95XX_BANK_SIZE;
+
+  Status = MvPca95xxReadRegs (I2cIo, PCA95XX_INPUT_REG + Bank, &RegVal);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: fail to read device register\n", __FUNCTION__));
+    return Status;
+  }
+
+  if (RegVal & (1 << (GpioPin % PCA95XX_BANK_SIZE))) {
+    *Value = 1;
+  } else {
+    *Value = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+Routine Description:
+
+  Sets the state of a GPIO pin
+
+Arguments:
+
+  This  - pointer to protocol
+  Gpio  - which pin to modify
+  Mode  - mode to set
+
+Returns:
+
+  EFI_SUCCESS           - GPIO set as requested
+  EFI_UNSUPPORTED       - Mode is not supported
+  EFI_INVALID_PARAMETER - Gpio pin is out of range
+**/
+STATIC
+EFI_STATUS
+MvPca95xxSet (
+  IN EMBEDDED_GPIO       *This,
+  IN EMBEDDED_GPIO_PIN   Gpio,
+  IN EMBEDDED_GPIO_MODE  Mode
+  )
+{
+  EFI_STATUS Status;
+  UINTN ControllerIndex;
+  UINTN GpioPin;
+
+  GpioPin = GPIO_PIN (Gpio);
+  ControllerIndex = GPIO_PORT (Gpio);
+
+  ASSERT_EFI_ERROR (MvPca95xxValidate (ControllerIndex, GpioPin));
+
+  switch (Mode) {
+  case GPIO_MODE_OUTPUT_0:
+  case GPIO_MODE_OUTPUT_1:
+    Status = MvPca95xxSetOutputValue (ControllerIndex, GpioPin, Mode);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: fail to set ouput value\n", __FUNCTION__));
+      return Status;
+    }
+
+  /* Fall-through */
+  case GPIO_MODE_INPUT:
+    Status = MvPca95xxSetDirection (ControllerIndex, GpioPin, Mode);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: fail to set direction\n", __FUNCTION__));
+      return Status;
+    }
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+Routine Description:
+
+  Sets the pull-up / pull-down resistor of a GPIO pin
+
+Arguments:
+
+  This  - pointer to protocol
+  Gpio  - which pin
+  Direction - pull-up, pull-down, or none
+
+Returns:
+
+  EFI_UNSUPPORTED - Can not perform the requested operation
+
+**/
+EFI_STATUS
+EFIAPI
+MvPca95xxSetPull (
+  IN EMBEDDED_GPIO       *This,
+  IN EMBEDDED_GPIO_PIN   Gpio,
+  IN EMBEDDED_GPIO_PULL  Direction
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+VOID
+MvPca95xxInitProtocol (
+  IN EMBEDDED_GPIO *GpioProtocol
+  )
+{
+  GpioProtocol->Get     = MvPca95xxGet;
+  GpioProtocol->Set     = MvPca95xxSet;
+  GpioProtocol->GetMode = MvPca95xxGetMode;
+  GpioProtocol->SetPull = MvPca95xxSetPull;
+}
+
+EFI_STATUS
+EFIAPI
+MvPca95xxEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  MARVELL_BOARD_DESC_PROTOCOL *MvBoardProtocol;
+  MV_BOARD_GPIO_DESCRIPTION *GpioDescription;
+  MV_GPIO_DEVICE_PATH *Pca95xxDevicePath;
+  EFI_STATUS Status;
+
+  /* Obtain list of available controllers */
+  Status = gBS->LocateProtocol (&gMarvellBoardDescProtocolGuid,
+                  NULL,
+                  (VOID **)&MvBoardProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: Cannot locate BoardDesc protocol\n",
+      __FUNCTION__));
+    return Status;
+  }
+
+  Status = MvBoardProtocol->GpioDescriptionGet (MvBoardProtocol,
+             &GpioDescription);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: Cannot get GPIO board desc from BoardDesc protocol\n",
+      __FUNCTION__));
+    return Status;
+  } else if (GpioDescription->GpioExpanders == NULL) {
+    /* Silently exit, if the board does not support the controllers */
+    return EFI_SUCCESS;
+  }
+
+  Pca95xxDevicePath = AllocateCopyPool (sizeof (MV_GPIO_DEVICE_PATH),
+                        &mDevicePathTemplate);
+  if (Pca95xxDevicePath == NULL) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: Fail to allocate Pca95xxDevicePath\n",
+      __FUNCTION__));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPca95xxInstance = AllocateZeroPool (sizeof (PCA95XX));
+  if (mPca95xxInstance == NULL) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: Fail to allocate mPca95xxInstance\n",
+      __FUNCTION__));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrPca95xxInstanceAlloc;
+  }
+
+  MvPca95xxInitProtocol (&mPca95xxInstance->GpioProtocol);
+
+  mPca95xxInstance->Signature = PCA95XX_GPIO_SIGNATURE;
+  mPca95xxInstance->GpioExpanders = GpioDescription->GpioExpanders;
+  mPca95xxInstance->GpioExpanderCount = GpioDescription->GpioExpanderCount;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &(mPca95xxInstance->ControllerHandle),
+                  &gEmbeddedGpioProtocolGuid,
+                  &(mPca95xxInstance->GpioProtocol),
+                  &gEfiDevicePathProtocolGuid,
+                  (EFI_DEVICE_PATH_PROTOCOL *)Pca95xxDevicePath,
+                  NULL);
+  if (EFI_ERROR (Status)) {
+    goto ErrInstallProtocols;
+  }
+
+  return EFI_SUCCESS;
+
+ErrInstallProtocols:
+  gBS->FreePool (mPca95xxInstance);
+
+ErrPca95xxInstanceAlloc:
+  gBS->FreePool (Pca95xxDevicePath);
+
+  return Status;
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 11/12] Marvell/Armada7k8k: Enable GPIO drivers compilation
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
                   ` (9 preceding siblings ...)
  2019-01-17 11:15 ` [platforms: PATCH v3 10/12] Marvell/Drivers: MvPca95xxDxe: Introduce GPIO expander driver Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 11:15 ` [platforms: PATCH v3 12/12] Marvell/Armada7k8k: Introduce NonDiscoverable device init routines Marcin Wojtas
  2019-01-17 12:03 ` [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Leif Lindholm
  12 siblings, 0 replies; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

Enable building new GPIO drivers before adding VBUS
pins handling. Update relevant boards .dsc files with
IO expander information.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc             | 2 ++
 Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc            | 4 ++--
 Platform/Marvell/Armada70x0Db/Armada70x0Db.fdf.inc        | 2 ++
 Platform/Marvell/Armada80x0Db/Armada80x0Db.fdf.inc        | 2 ++
 Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.fdf.inc | 2 ++
 5 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc b/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
index 92ff1da..5b8f4e9 100644
--- a/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
+++ b/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
@@ -454,6 +454,8 @@
   Silicon/Marvell/Armada7k8k/Drivers/PlatInitDxe/PlatInitDxe.inf
 
   # Platform drivers
+  Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
+  Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
   Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf
   MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf
   Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.inf
diff --git a/Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc b/Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc
index a935f36..31815e4 100644
--- a/Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc
+++ b/Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc
@@ -89,8 +89,8 @@
   gMarvellTokenSpaceGuid.PcdChip1MppSel6|{ 0xE, 0xE, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
 
   # I2C
-  gMarvellTokenSpaceGuid.PcdI2cSlaveAddresses|{ 0x50, 0x57, 0x60 }
-  gMarvellTokenSpaceGuid.PcdI2cSlaveBuses|{ 0x0, 0x0, 0x0 }
+  gMarvellTokenSpaceGuid.PcdI2cSlaveAddresses|{ 0x50, 0x57, 0x60, 0x21 }
+  gMarvellTokenSpaceGuid.PcdI2cSlaveBuses|{ 0x0, 0x0, 0x0, 0x0 }
   gMarvellTokenSpaceGuid.PcdI2cControllersEnabled|{ 0x1, 0x1 }
   gMarvellTokenSpaceGuid.PcdEepromI2cAddresses|{ 0x50, 0x57 }
   gMarvellTokenSpaceGuid.PcdEepromI2cBuses|{ 0x0, 0x0 }
diff --git a/Platform/Marvell/Armada70x0Db/Armada70x0Db.fdf.inc b/Platform/Marvell/Armada70x0Db/Armada70x0Db.fdf.inc
index b7e7a65..7129606 100644
--- a/Platform/Marvell/Armada70x0Db/Armada70x0Db.fdf.inc
+++ b/Platform/Marvell/Armada70x0Db/Armada70x0Db.fdf.inc
@@ -12,6 +12,8 @@
 
 # Per-board additional content of the DXE phase firmware volume
 
+  INF Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
+
   # DTB
   INF RuleOverride = DTB Silicon/Marvell/Armada7k8k/DeviceTree/Armada70x0Db.inf
 
diff --git a/Platform/Marvell/Armada80x0Db/Armada80x0Db.fdf.inc b/Platform/Marvell/Armada80x0Db/Armada80x0Db.fdf.inc
index 81a81d0..f2fcc55 100644
--- a/Platform/Marvell/Armada80x0Db/Armada80x0Db.fdf.inc
+++ b/Platform/Marvell/Armada80x0Db/Armada80x0Db.fdf.inc
@@ -12,6 +12,8 @@
 
 # Per-board additional content of the DXE phase firmware volume
 
+  INF Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
+
   # DTB
   INF RuleOverride = DTB Silicon/Marvell/Armada7k8k/DeviceTree/Armada80x0Db.inf
 
diff --git a/Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.fdf.inc b/Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.fdf.inc
index 326da2e..254fcee 100644
--- a/Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.fdf.inc
+++ b/Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.fdf.inc
@@ -12,6 +12,8 @@
 
 # Per-board additional content of the DXE phase firmware volume
 
+  INF Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
+
   # DTB
   INF RuleOverride = DTB Silicon/Marvell/Armada7k8k/DeviceTree/Armada80x0McBin.inf
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [platforms: PATCH v3 12/12] Marvell/Armada7k8k: Introduce NonDiscoverable device init routines
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
                   ` (10 preceding siblings ...)
  2019-01-17 11:15 ` [platforms: PATCH v3 11/12] Marvell/Armada7k8k: Enable GPIO drivers compilation Marcin Wojtas
@ 2019-01-17 11:15 ` Marcin Wojtas
  2019-01-17 12:03 ` [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Leif Lindholm
  12 siblings, 0 replies; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 11:15 UTC (permalink / raw)
  To: edk2-devel; +Cc: leif.lindholm, ard.biesheuvel, nadavh, mw, jsd, jaz, kostap

To abstract the initialization required for non-discoverable devices,
which is often platform specific (e.g. enable GPIO-driven power supply),
introduce a NonDiscoverableInitLib for use by the NonDiscoverable code,
for which each platform can supply its own version.

Add XHCI power supply (so called 'VBUS') enabling routines
for supported platforms (Armada70x0Db, Armada80x0Db, Armada80x0McBin).

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 Silicon/Marvell/Marvell.dec                                                         |   1 +
 Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc                                       |   1 +
 Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc                                      |   3 +
 Platform/Marvell/Armada80x0Db/Armada80x0Db.dsc                                      |   3 +
 Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.dsc                               |   3 +
 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf     |  49 +++++++++
 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf     |  50 +++++++++
 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf |  50 +++++++++
 Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.inf                   |   1 +
 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h       |  23 +++++
 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h       |  28 ++++++
 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h   |  20 ++++
 Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h                            |  28 ++++++
 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c       |  96 ++++++++++++++++++
 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c       | 106 ++++++++++++++++++++
 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c   |  71 +++++++++++++
 Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.c                     |  13 ++-
 17 files changed, 543 insertions(+), 3 deletions(-)
 create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
 create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
 create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
 create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
 create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
 create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h
 create mode 100644 Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h
 create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
 create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
 create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c

diff --git a/Silicon/Marvell/Marvell.dec b/Silicon/Marvell/Marvell.dec
index ac922a0..c34d783 100644
--- a/Silicon/Marvell/Marvell.dec
+++ b/Silicon/Marvell/Marvell.dec
@@ -64,6 +64,7 @@
   ArmadaIcuLib|Include/Library/ArmadaIcuLib.h
   ArmadaSoCDescLib|Include/Library/ArmadaSoCDescLib.h
   MvGpioLib|Include/Library/MvGpioLib.h
+  NonDiscoverableInitLib|Include/Library/NonDiscoverableInitLib.h
   SampleAtResetLib|Include/Library/SampleAtResetLib.h
 
 [Protocols]
diff --git a/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc b/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
index 5b8f4e9..eafcd6e 100644
--- a/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
+++ b/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
@@ -37,6 +37,7 @@
   ArmPlatformLib|Silicon/Marvell/Armada7k8k/Library/Armada7k8kLib/Armada7k8kLib.inf
   ComPhyLib|Silicon/Marvell/Library/ComPhyLib/ComPhyLib.inf
   MppLib|Silicon/Marvell/Library/MppLib/MppLib.inf
+  MvGpioLib|Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
   NorFlashInfoLib|EmbeddedPkg/Library/NorFlashInfoLib/NorFlashInfoLib.inf
   SampleAtResetLib|Silicon/Marvell/Armada7k8k/Library/Armada7k8kSampleAtResetLib/Armada7k8kSampleAtResetLib.inf
   UtmiPhyLib|Silicon/Marvell/Library/UtmiPhyLib/UtmiPhyLib.inf
diff --git a/Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc b/Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc
index 31815e4..e8cd177 100644
--- a/Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc
+++ b/Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc
@@ -48,6 +48,9 @@
 
 !include Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
 
+[LibraryClasses.common]
+  NonDiscoverableInitLib|Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
+
 [Components.common]
   Silicon/Marvell/Armada7k8k/DeviceTree/Armada70x0Db.inf
 
diff --git a/Platform/Marvell/Armada80x0Db/Armada80x0Db.dsc b/Platform/Marvell/Armada80x0Db/Armada80x0Db.dsc
index 42f7bd3..8e8c2ba 100644
--- a/Platform/Marvell/Armada80x0Db/Armada80x0Db.dsc
+++ b/Platform/Marvell/Armada80x0Db/Armada80x0Db.dsc
@@ -48,6 +48,9 @@
 
 !include Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
 
+[LibraryClasses.common]
+  NonDiscoverableInitLib|Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
+
 [Components.common]
   Silicon/Marvell/Armada7k8k/DeviceTree/Armada80x0Db.inf
 
diff --git a/Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.dsc b/Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.dsc
index 077224d..d080136 100644
--- a/Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.dsc
+++ b/Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.dsc
@@ -49,6 +49,9 @@
 
 !include Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
 
+[LibraryClasses.common]
+  NonDiscoverableInitLib|Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
+
 [Components.common]
   Silicon/Marvell/Armada7k8k/DeviceTree/Armada80x0McBin.inf
 
diff --git a/Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf b/Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
new file mode 100644
index 0000000..56c08ec
--- /dev/null
+++ b/Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
@@ -0,0 +1,49 @@
+## @file
+#
+#  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+#  IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = Armada70x0DbNonDiscoverableInitLib
+  FILE_GUID                      = 151b04bc-9195-4380-b1fa-987130b450f0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NonDiscoverableInitLib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = AARCH64
+#
+
+[Sources]
+  NonDiscoverableInitLib.c
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+  DebugLib
+  IoLib
+  MvGpioLib
+
+[Protocols]
+  gEmbeddedGpioProtocolGuid
+
+[Depex]
+  gMarvellPlatformInitCompleteProtocolGuid
diff --git a/Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf b/Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
new file mode 100644
index 0000000..fe21e52
--- /dev/null
+++ b/Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
@@ -0,0 +1,50 @@
+## @file
+#
+#  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+#  Copyright (c) 2018, Marvell International Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+#  IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = Armada80x0DbNonDiscoverableInitLib
+  FILE_GUID                      = 719c91d5-25aa-4366-988a-1642ae3a6734
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NonDiscoverableInitLib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = AARCH64
+#
+
+[Sources]
+  NonDiscoverableInitLib.c
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+  DebugLib
+  IoLib
+  MvGpioLib
+
+[Protocols]
+  gEmbeddedGpioProtocolGuid
+
+[Depex]
+  gMarvellPlatformInitCompleteProtocolGuid
diff --git a/Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf b/Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
new file mode 100644
index 0000000..60fc9a1
--- /dev/null
+++ b/Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
@@ -0,0 +1,50 @@
+## @file
+#
+#  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+#  Copyright (c) 2018, Marvell International Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+#  IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = Armada80x0McBinNonDiscoverableInitLib
+  FILE_GUID                      = 470963c4-476e-4b85-a7c4-17868177f441
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NonDiscoverableInitLib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = AARCH64
+#
+
+[Sources]
+  NonDiscoverableInitLib.c
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+  DebugLib
+  IoLib
+  MvGpioLib
+
+[Protocols]
+  gEmbeddedGpioProtocolGuid
+
+[Depex]
+  gMarvellPlatformInitCompleteProtocolGuid
diff --git a/Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.inf b/Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.inf
index 98e5b0c..3f9f7bc 100644
--- a/Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.inf
+++ b/Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.inf
@@ -50,6 +50,7 @@
 
 [LibraryClasses]
   NonDiscoverableDeviceRegistrationLib
+  NonDiscoverableInitLib
   UefiDriverEntryPoint
 
 [Protocols]
diff --git a/Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h b/Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
new file mode 100644
index 0000000..8a0e424
--- /dev/null
+++ b/Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
@@ -0,0 +1,23 @@
+/**
+*
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+#ifndef __NON_DISCOVERABLE_INIT_LIB_H__
+#define __NON_DISCOVERABLE_INIT_LIB_H__
+
+#define ARMADA_70x0_DB_IO_EXPANDER0       0
+#define ARMADA_70x0_DB_VBUS0_PIN          0
+#define ARMADA_70x0_DB_VBUS0_LIMIT_PIN    4
+#define ARMADA_70x0_DB_VBUS1_PIN          1
+#define ARMADA_70x0_DB_VBUS1_LIMIT_PIN    5
+
+#endif
diff --git a/Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h b/Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
new file mode 100644
index 0000000..64373ff
--- /dev/null
+++ b/Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
@@ -0,0 +1,28 @@
+/**
+*
+*  Copyright (c) 2017, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+#ifndef __NON_DISCOVERABLE_INIT_LIB_H__
+#define __NON_DISCOVERABLE_INIT_LIB_H__
+
+#define ARMADA_80x0_DB_IO_EXPANDER0       0
+#define ARMADA_80x0_DB_VBUS0_PIN          0
+#define ARMADA_80x0_DB_VBUS0_LIMIT_PIN    4
+#define ARMADA_80x0_DB_VBUS1_PIN          1
+#define ARMADA_80x0_DB_VBUS1_LIMIT_PIN    5
+
+#define ARMADA_80x0_DB_IO_EXPANDER1       1
+#define ARMADA_80x0_DB_VBUS2_PIN          0
+#define ARMADA_80x0_DB_VBUS2_LIMIT_PIN    4
+
+#endif
diff --git a/Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h b/Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h
new file mode 100644
index 0000000..38e1f20
--- /dev/null
+++ b/Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h
@@ -0,0 +1,20 @@
+/**
+*
+*  Copyright (c) 2017, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+#ifndef __NON_DISCOVERABLE_INIT_LIB_H__
+#define __NON_DISCOVERABLE_INIT_LIB_H__
+
+#define ARMADA_80x0_MCBIN_VBUS0_PIN               15
+
+#endif
diff --git a/Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h b/Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h
new file mode 100644
index 0000000..18de24f
--- /dev/null
+++ b/Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h
@@ -0,0 +1,28 @@
+/**
+*
+*  Copyright (c) 2017, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __NON_DISCOVERABLE_INIT_LIB_H__
+#define __NON_DISCOVERABLE_INIT_LIB_H__
+
+#include <Library/NonDiscoverableDeviceRegistrationLib.h>
+
+NON_DISCOVERABLE_DEVICE_INIT
+EFIAPI
+NonDiscoverableDeviceInitializerGet (
+  IN  NON_DISCOVERABLE_DEVICE_TYPE  Type,
+  IN  UINTN                         Index
+  );
+
+#endif
diff --git a/Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c b/Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
new file mode 100644
index 0000000..d8dba6e
--- /dev/null
+++ b/Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
@@ -0,0 +1,96 @@
+/**
+*
+*  Copyright (c) 2017, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/MvGpioLib.h>
+#include <Library/NonDiscoverableDeviceRegistrationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/NonDiscoverableDevice.h>
+
+#include "NonDiscoverableInitLib.h"
+
+STATIC CONST MV_GPIO_PIN mXhciVbusPins[] = {
+  {
+    ARMADA_70x0_DB_IO_EXPANDER0,
+    ARMADA_70x0_DB_VBUS0_PIN,
+    TRUE,
+  },
+  {
+    ARMADA_70x0_DB_IO_EXPANDER0,
+    ARMADA_70x0_DB_VBUS0_LIMIT_PIN,
+    TRUE,
+  },
+  {
+    ARMADA_70x0_DB_IO_EXPANDER0,
+    ARMADA_70x0_DB_VBUS1_PIN,
+    TRUE,
+  },
+  {
+    ARMADA_70x0_DB_IO_EXPANDER0,
+    ARMADA_70x0_DB_VBUS1_LIMIT_PIN,
+    TRUE,
+  },
+};
+
+STATIC
+EFI_STATUS
+EFIAPI
+XhciInit (
+  IN  NON_DISCOVERABLE_DEVICE  *This
+  )
+{
+  CONST MV_GPIO_PIN   *VbusPin;
+  EMBEDDED_GPIO_MODE   Mode;
+  EMBEDDED_GPIO_PIN    Gpio;
+  EMBEDDED_GPIO       *GpioProtocol;
+  EFI_STATUS           Status;
+  UINTN                Index;
+
+  Status = MvGpioGetProtocol (MV_GPIO_DRIVER_TYPE_PCA95XX, &GpioProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Unable to find GPIO protocol\n", __FUNCTION__));
+    return Status;
+  }
+
+  VbusPin = mXhciVbusPins;
+  for (Index = 0; Index < ARRAY_SIZE (mXhciVbusPins); Index++) {
+    Mode = VbusPin->ActiveHigh ? GPIO_MODE_OUTPUT_1 : GPIO_MODE_OUTPUT_0;
+    Gpio = GPIO (VbusPin->ControllerId, VbusPin->PinNumber);
+    GpioProtocol->Set (GpioProtocol, Gpio, Mode);
+    VbusPin++;
+  }
+
+  return EFI_SUCCESS;
+}
+
+NON_DISCOVERABLE_DEVICE_INIT
+EFIAPI
+NonDiscoverableDeviceInitializerGet (
+  IN  NON_DISCOVERABLE_DEVICE_TYPE  Type,
+  IN  UINTN                         Index
+  )
+{
+  if (Type == NonDiscoverableDeviceTypeXhci) {
+        return XhciInit;
+  }
+
+  return NULL;
+}
diff --git a/Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c b/Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
new file mode 100644
index 0000000..e7a1d1e
--- /dev/null
+++ b/Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
@@ -0,0 +1,106 @@
+/**
+*
+*  Copyright (c) 2017, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/MvGpioLib.h>
+#include <Library/NonDiscoverableDeviceRegistrationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/NonDiscoverableDevice.h>
+
+#include "NonDiscoverableInitLib.h"
+
+STATIC CONST MV_GPIO_PIN mXhciVbusPins[] = {
+  {
+    ARMADA_80x0_DB_IO_EXPANDER0,
+    ARMADA_80x0_DB_VBUS0_PIN,
+    TRUE,
+  },
+  {
+    ARMADA_80x0_DB_IO_EXPANDER0,
+    ARMADA_80x0_DB_VBUS0_LIMIT_PIN,
+    TRUE,
+  },
+  {
+    ARMADA_80x0_DB_IO_EXPANDER0,
+    ARMADA_80x0_DB_VBUS1_PIN,
+    TRUE,
+  },
+  {
+    ARMADA_80x0_DB_IO_EXPANDER0,
+    ARMADA_80x0_DB_VBUS1_LIMIT_PIN,
+    TRUE,
+  },
+  {
+    ARMADA_80x0_DB_IO_EXPANDER1,
+    ARMADA_80x0_DB_VBUS2_PIN,
+    TRUE,
+  },
+  {
+    ARMADA_80x0_DB_IO_EXPANDER1,
+    ARMADA_80x0_DB_VBUS2_LIMIT_PIN,
+    TRUE,
+  },
+};
+
+STATIC
+EFI_STATUS
+EFIAPI
+XhciInit (
+  IN  NON_DISCOVERABLE_DEVICE  *This
+  )
+{
+  CONST MV_GPIO_PIN   *VbusPin;
+  EMBEDDED_GPIO_MODE   Mode;
+  EMBEDDED_GPIO_PIN    Gpio;
+  EMBEDDED_GPIO       *GpioProtocol;
+  EFI_STATUS           Status;
+  UINTN                Index;
+
+  Status = MvGpioGetProtocol (MV_GPIO_DRIVER_TYPE_PCA95XX, &GpioProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Unable to find GPIO protocol\n", __FUNCTION__));
+    return Status;
+  }
+
+  VbusPin = mXhciVbusPins;
+  for (Index = 0; Index < ARRAY_SIZE (mXhciVbusPins); Index++) {
+    Mode = VbusPin->ActiveHigh ? GPIO_MODE_OUTPUT_1 : GPIO_MODE_OUTPUT_0;
+    Gpio = GPIO (VbusPin->ControllerId, VbusPin->PinNumber);
+    GpioProtocol->Set (GpioProtocol, Gpio, Mode);
+    VbusPin++;
+  }
+
+  return EFI_SUCCESS;
+}
+
+NON_DISCOVERABLE_DEVICE_INIT
+EFIAPI
+NonDiscoverableDeviceInitializerGet (
+  IN  NON_DISCOVERABLE_DEVICE_TYPE  Type,
+  IN  UINTN                         Index
+  )
+{
+  if (Type == NonDiscoverableDeviceTypeXhci) {
+        return XhciInit;
+  }
+
+  return NULL;
+}
diff --git a/Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c b/Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c
new file mode 100644
index 0000000..d1055cb
--- /dev/null
+++ b/Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c
@@ -0,0 +1,71 @@
+/**
+*
+*  Copyright (c) 2017, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/MvGpioLib.h>
+#include <Library/NonDiscoverableDeviceRegistrationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/NonDiscoverableDevice.h>
+
+#include "NonDiscoverableInitLib.h"
+
+STATIC CONST MV_GPIO_PIN mXhciVbusPin = {
+  MV_GPIO_CP0_CONTROLLER1,
+  ARMADA_80x0_MCBIN_VBUS0_PIN,
+  TRUE,
+};
+
+STATIC
+EFI_STATUS
+EFIAPI
+XhciInit (
+  IN  NON_DISCOVERABLE_DEVICE  *This
+  )
+{
+  EMBEDDED_GPIO  *GpioProtocol;
+  EFI_STATUS      Status;
+
+  Status = MvGpioGetProtocol (MV_GPIO_DRIVER_TYPE_SOC_CONTROLLER, &GpioProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Unable to find GPIO protocol\n", __FUNCTION__));
+    return Status;
+  }
+
+  GpioProtocol->Set (GpioProtocol,
+                  GPIO (mXhciVbusPin.ControllerId, mXhciVbusPin.PinNumber),
+                  GPIO_MODE_OUTPUT_1);
+
+  return Status;
+}
+
+NON_DISCOVERABLE_DEVICE_INIT
+EFIAPI
+NonDiscoverableDeviceInitializerGet (
+  IN  NON_DISCOVERABLE_DEVICE_TYPE  Type,
+  IN  UINTN                         Index
+  )
+{
+  if (Type == NonDiscoverableDeviceTypeXhci) {
+        return XhciInit;
+  }
+
+  return NULL;
+}
diff --git a/Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.c b/Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.c
index 116e9d4..74040b2 100644
--- a/Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.c
+++ b/Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.c
@@ -36,6 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <Library/DebugLib.h>
 #include <Library/NonDiscoverableDeviceRegistrationLib.h>
+#include <Library/NonDiscoverableInitLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 
 #include <Protocol/BoardDesc.h>
@@ -57,7 +58,9 @@ NonDiscoverableInitXhci (
     Status = RegisterNonDiscoverableMmioDevice (
                      NonDiscoverableDeviceTypeXhci,
                      Desc[i].SoC->XhciDmaType,
-                     NULL,
+                     NonDiscoverableDeviceInitializerGet (
+                       NonDiscoverableDeviceTypeXhci,
+                       i),
                      NULL,
                      1,
                      Desc[i].SoC->XhciBaseAddress,
@@ -86,7 +89,9 @@ NonDiscoverableInitAhci (
     Status = RegisterNonDiscoverableMmioDevice (
                      NonDiscoverableDeviceTypeAhci,
                      Desc[i].SoC->AhciDmaType,
-                     NULL,
+                     NonDiscoverableDeviceInitializerGet (
+                       NonDiscoverableDeviceTypeAhci,
+                       i),
                      NULL,
                      1,
                      Desc[i].SoC->AhciBaseAddress,
@@ -115,7 +120,9 @@ NonDiscoverableInitSdhci (
     Status = RegisterNonDiscoverableMmioDevice (
                      NonDiscoverableDeviceTypeSdhci,
                      Desc[i].SoC->SdMmcDmaType,
-                     NULL,
+                     NonDiscoverableDeviceInitializerGet (
+                       NonDiscoverableDeviceTypeSdhci,
+                       i),
                      NULL,
                      1,
                      Desc[i].SoC->SdMmcBaseAddress,
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 03/12] Marvell/Library: Introduce MvGpioLib class
  2019-01-17 11:15 ` [platforms: PATCH v3 03/12] Marvell/Library: Introduce MvGpioLib class Marcin Wojtas
@ 2019-01-17 11:33   ` Leif Lindholm
  2019-01-17 12:19     ` Marcin Wojtas
  0 siblings, 1 reply; 24+ messages in thread
From: Leif Lindholm @ 2019-01-17 11:33 UTC (permalink / raw)
  To: Marcin Wojtas; +Cc: edk2-devel, ard.biesheuvel, nadavh, jsd, jaz, kostap

(Can drop the "class" from subject line)

With that:
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

On Thu, Jan 17, 2019 at 12:15:06PM +0100, Marcin Wojtas wrote:
> Following patches will add two drivers that are capable
> of producing the generic EMBEDDED_GPIO protocol. In order
> to handle a situation, when the consumer module attempts
> to locate and open a proper protocol, add a library
> helper function.
> 
> In order to ease description of used GPIO pins and controllers
> of the Armada 7k8k platforms, add the common enum types.
> 
> Signed-off-by: Marcin Wojtas <mw@semihalf.com>
> ---
>  Silicon/Marvell/Marvell.dec                     |   1 +
>  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf |  32 +++++
>  Silicon/Marvell/Include/Library/MvGpioLib.h     |  68 ++++++++++
>  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c   | 132 ++++++++++++++++++++
>  4 files changed, 233 insertions(+)
>  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
>  create mode 100644 Silicon/Marvell/Include/Library/MvGpioLib.h
>  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> 
> diff --git a/Silicon/Marvell/Marvell.dec b/Silicon/Marvell/Marvell.dec
> index 616624e..ac922a0 100644
> --- a/Silicon/Marvell/Marvell.dec
> +++ b/Silicon/Marvell/Marvell.dec
> @@ -63,6 +63,7 @@
>    ArmadaBoardDescLib|Include/Library/ArmadaBoardDescLib.h
>    ArmadaIcuLib|Include/Library/ArmadaIcuLib.h
>    ArmadaSoCDescLib|Include/Library/ArmadaSoCDescLib.h
> +  MvGpioLib|Include/Library/MvGpioLib.h
>    SampleAtResetLib|Include/Library/SampleAtResetLib.h
>  
>  [Protocols]
> diff --git a/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> new file mode 100644
> index 0000000..3bc54ce
> --- /dev/null
> +++ b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> @@ -0,0 +1,32 @@
> +## @file
> +#
> +#  Copyright (C) 2018, Marvell International Ltd. and its affiliates<BR>
> +#
> +#  This program and the accompanying materials are licensed and made available
> +#  under the terms and conditions of the BSD License which accompanies this
> +#  distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> +#  IMPLIED.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001A
> +  BASE_NAME                      = MvGpioLib
> +  FILE_GUID                      = f4386b44-6bc2-4fa1-9989-8513bbb22692
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = MvGpioLib
> +
> +[Sources]
> +  MvGpioLib.c
> +
> +[Packages]
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Marvell/Marvell.dec
> +
> +[LibraryClasses]
> +  DebugLib
> diff --git a/Silicon/Marvell/Include/Library/MvGpioLib.h b/Silicon/Marvell/Include/Library/MvGpioLib.h
> new file mode 100644
> index 0000000..a14acdf
> --- /dev/null
> +++ b/Silicon/Marvell/Include/Library/MvGpioLib.h
> @@ -0,0 +1,68 @@
> +/**
> +*
> +*  Copyright (C) 2018, Marvell International Ltd. and its affiliates.
> +*
> +*  This program and the accompanying materials are licensed and made available
> +*  under the terms and conditions of the BSD License which accompanies this
> +*  distribution. The full text of the license may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +#ifndef __MV_GPIO_LIB_H__
> +#define __MV_GPIO_LIB_H__
> +
> +#include <Protocol/EmbeddedGpio.h>
> +
> +typedef enum {
> +  MV_GPIO_DRIVER_TYPE_SOC_CONTROLLER,
> +  MV_GPIO_DRIVER_TYPE_PCA95XX,
> +} MV_GPIO_DRIVER_TYPE;
> +
> +typedef enum {
> +  MV_GPIO_AP806_CONTROLLER0,
> +  MV_GPIO_CP0_CONTROLLER0,
> +  MV_GPIO_CP0_CONTROLLER1,
> +  MV_GPIO_CP1_CONTROLLER0,
> +  MV_GPIO_CP1_CONTROLLER1,
> +  MV_GPIO_CP2_CONTROLLER0,
> +  MV_GPIO_CP2_CONTROLLER1,
> +} MV_GPIO_SOC_CONTROLLER_TYPE;
> +
> +typedef enum {
> +  PCA9505_ID,
> +  PCA9534_ID,
> +  PCA9535_ID,
> +  PCA9536_ID,
> +  PCA9537_ID,
> +  PCA9538_ID,
> +  PCA9539_ID,
> +  PCA9554_ID,
> +  PCA9555_ID,
> +  PCA9556_ID,
> +  PCA9557_ID,
> +  PCA95XX_MAX_ID,
> +} MV_GPIO_EXPANDER_TYPE_PCA95XX;
> +
> +typedef struct {
> +  VENDOR_DEVICE_PATH        Header;
> +  MV_GPIO_DRIVER_TYPE       GpioDriverType;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} MV_GPIO_DEVICE_PATH;
> +
> +typedef struct {
> +  UINTN    ControllerId;
> +  UINTN    PinNumber;
> +  BOOLEAN  ActiveHigh;
> +} MV_GPIO_PIN;
> +
> +EFI_STATUS
> +EFIAPI
> +MvGpioGetProtocol (
> +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> +  );
> +
> +#endif // __MV_GPIO_LIB_H__
> diff --git a/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> new file mode 100644
> index 0000000..a95d5ae
> --- /dev/null
> +++ b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> @@ -0,0 +1,132 @@
> +/**
> +*
> +*  Copyright (C) 2018, Marvell International Ltd. and its affiliates.
> +*
> +*  This program and the accompanying materials are licensed and made available
> +*  under the terms and conditions of the BSD License which accompanies this
> +*  distribution. The full text of the license may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +#include <Uefi.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/MvGpioLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <Protocol/EmbeddedGpio.h>
> +
> +/*
> + * Check if the driver type matches the requested value.
> + * In case of the success open the GPIO protocol and return.
> + */
> +STATIC
> +EFI_STATUS
> +MvGpioFindMatchingDriver (
> +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> +  IN     EFI_HANDLE             HandleBuffer,
> +  IN     EFI_DEVICE_PATH       *DevicePath,
> +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> +  )
> +{
> +  MV_GPIO_DEVICE_PATH *GpioDevicePath;
> +  EFI_STATUS           Status;
> +
> +  while (!IsDevicePathEndType (DevicePath)) {
> +    /* Check if GpioDriverType matches one found in the device path */
> +    GpioDevicePath = (MV_GPIO_DEVICE_PATH *)DevicePath;
> +    if (GpioDevicePath->GpioDriverType != GpioDriverType) {
> +      DevicePath = NextDevicePathNode (DevicePath);
> +      continue;
> +    }
> +
> +    /*
> +     * Open GpioProtocol. With EFI_OPEN_PROTOCOL_GET_PROTOCOL attribute
> +     * the consumer is not obliged to call CloseProtocol.
> +     */
> +    Status = gBS->OpenProtocol (HandleBuffer,
> +                    &gEmbeddedGpioProtocolGuid,
> +                    (VOID **)GpioProtocol,
> +                    gImageHandle,
> +                    NULL,
> +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> +    return Status;
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/*
> + * Select desired protocol producer upon MV_GPIO_DRIVER_TYPE
> + * field of driver's MV_GPIO_DEVICE_PATH.
> + */
> +EFI_STATUS
> +EFIAPI
> +MvGpioGetProtocol (
> +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> +  )
> +{
> +  EFI_DEVICE_PATH     *DevicePath;
> +  EFI_HANDLE          *HandleBuffer;
> +  EFI_STATUS           Status;
> +  UINTN                HandleCount;
> +  UINTN                Index;
> +
> +  /* Locate Handles of all EMBEDDED_GPIO producers */
> +  Status = gBS->LocateHandleBuffer (ByProtocol,
> +                  &gEmbeddedGpioProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Unable to locate handles\n", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  /* Iterate over all protocol producers */
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    /* Open device path protocol installed on each handle */
> +    Status = gBS->OpenProtocol (HandleBuffer[Index],
> +                    &gEfiDevicePathProtocolGuid,
> +                    (VOID **)&DevicePath,
> +                    gImageHandle,
> +                    NULL,
> +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a: Unable to find DevicePath\n", __FUNCTION__));
> +      continue;
> +    }
> +
> +    /*
> +     * Check if the driver type matches the requested value.
> +     * In case of the success open the GPIO protocol and return.
> +     * If there is no match, repeat procedure with the next handle.
> +     */
> +    Status = MvGpioFindMatchingDriver (GpioDriverType,
> +               HandleBuffer[Index],
> +               DevicePath,
> +               GpioProtocol);
> +    if (Status == EFI_NOT_FOUND) {
> +      continue;
> +    } else if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR,
> +        "%a: Unable to open GPIO protocol\n",
> +        __FUNCTION__));
> +    }
> +
> +    gBS->FreePool (HandleBuffer);
> +
> +    return Status;
> +  }
> +
> +  /* No matching GPIO protocol producer was found */
> +  gBS->FreePool (HandleBuffer);
> +
> +  return EFI_NOT_FOUND;
> +}
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 05/12] Marvell/Armada70x0Db: Extend board description library with GPIO
  2019-01-17 11:15 ` [platforms: PATCH v3 05/12] Marvell/Armada70x0Db: " Marcin Wojtas
@ 2019-01-17 11:34   ` Leif Lindholm
  0 siblings, 0 replies; 24+ messages in thread
From: Leif Lindholm @ 2019-01-17 11:34 UTC (permalink / raw)
  To: Marcin Wojtas; +Cc: edk2-devel, ard.biesheuvel, nadavh, jsd, jaz, kostap

On Thu, Jan 17, 2019 at 12:15:08PM +0100, Marcin Wojtas wrote:
> This patch implements ArmadaBoarDescLib library for
> Armada70x0Db comunity board and introduces ArmadaBoardGpioGet
> routine with per-board GPIO expander description.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Marcin Wojtas <mw@semihalf.com>

Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

> ---
>  Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c | 24 ++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c b/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c
> index 48c68e4..f0133ec 100644
> --- a/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c
> +++ b/Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c
> @@ -19,9 +19,33 @@
>  #include <Library/DebugLib.h>
>  #include <Library/IoLib.h>
>  #include <Library/MemoryAllocationLib.h>
> +#include <Library/MvGpioLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
>  
>  //
> +// GPIO Expander
> +//
> +STATIC MV_GPIO_EXPANDER mGpioExpander = {
> +  PCA9555_ID,
> +  0x21,
> +  0x0,
> +};
> +
> +
> +EFI_STATUS
> +EFIAPI
> +ArmadaBoardGpioExpanderGet (
> +  IN OUT MV_GPIO_EXPANDER **GpioExpanders,
> +  IN OUT UINTN             *GpioExpanderCount
> +  )
> +{
> +  *GpioExpanderCount = 1;
> +  *GpioExpanders = &mGpioExpander;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
>  // Order of devices in SdMmcDescTemplate has to be in par with ArmadaSoCDescLib
>  //
>  STATIC
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 06/12] Marvell/Armada80x0Db: Extend board description library with GPIO
  2019-01-17 11:15 ` [platforms: PATCH v3 06/12] Marvell/Armada80x0Db: " Marcin Wojtas
@ 2019-01-17 11:34   ` Leif Lindholm
  0 siblings, 0 replies; 24+ messages in thread
From: Leif Lindholm @ 2019-01-17 11:34 UTC (permalink / raw)
  To: Marcin Wojtas; +Cc: edk2-devel, ard.biesheuvel, nadavh, jsd, jaz, kostap

On Thu, Jan 17, 2019 at 12:15:09PM +0100, Marcin Wojtas wrote:
> This patch implements ArmadaBoarDescLib library for
> Armada80x0Db board and introduces ArmadaBoardGpioGet
> routine with per-board GPIO expander description.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Marcin Wojtas <mw@semihalf.com>

Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

> ---
>  Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c | 30 ++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c b/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c
> index feb69ad..61b6202 100644
> --- a/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c
> +++ b/Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c
> @@ -19,9 +19,39 @@
>  #include <Library/DebugLib.h>
>  #include <Library/IoLib.h>
>  #include <Library/MemoryAllocationLib.h>
> +#include <Library/MvGpioLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
>  
>  //
> +// GPIO Expanders
> +//
> +STATIC MV_GPIO_EXPANDER mGpioExpanders[] = {
> +  {
> +    PCA9555_ID,
> +    0x21,
> +    0x0,
> +  },
> +  {
> +    PCA9555_ID,
> +    0x25,
> +    0x0,
> +  },
> +};
> +
> +EFI_STATUS
> +EFIAPI
> +ArmadaBoardGpioExpanderGet (
> +  IN OUT MV_GPIO_EXPANDER **GpioExpanders,
> +  IN OUT UINTN             *GpioExpanderCount
> +  )
> +{
> +  *GpioExpanderCount = ARRAY_SIZE (mGpioExpanders);
> +  *GpioExpanders = mGpioExpanders;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
>  // Order of devices in SdMmcDescTemplate has to be in par with ArmadaSoCDescLib
>  //
>  STATIC
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 07/12] Marvell/Drivers: MvBoardDesc: Extend protocol with GPIO support
  2019-01-17 11:15 ` [platforms: PATCH v3 07/12] Marvell/Drivers: MvBoardDesc: Extend protocol with GPIO support Marcin Wojtas
@ 2019-01-17 11:50   ` Leif Lindholm
  0 siblings, 0 replies; 24+ messages in thread
From: Leif Lindholm @ 2019-01-17 11:50 UTC (permalink / raw)
  To: Marcin Wojtas; +Cc: edk2-devel, ard.biesheuvel, nadavh, jsd, jaz, kostap

On Thu, Jan 17, 2019 at 12:15:10PM +0100, Marcin Wojtas wrote:
> Introduce new callback that can provide information
> about GPIO SoC controllers, as well as on-board
> I2C IO expanders. According ArmadaSoCDescLib
> ArmadaBoardDescLib routines are used for
> obtaining required data.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Marcin Wojtas <mw@semihalf.com>

Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

> ---
>  Silicon/Marvell/Include/Protocol/BoardDesc.h       |  8 ++++
>  Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c | 50 ++++++++++++++++++++
>  2 files changed, 58 insertions(+)
> 
> diff --git a/Silicon/Marvell/Include/Protocol/BoardDesc.h b/Silicon/Marvell/Include/Protocol/BoardDesc.h
> index 1d57a16..02905ea 100644
> --- a/Silicon/Marvell/Include/Protocol/BoardDesc.h
> +++ b/Silicon/Marvell/Include/Protocol/BoardDesc.h
> @@ -50,6 +50,13 @@ EFI_STATUS
>  
>  typedef
>  EFI_STATUS
> +(EFIAPI *MV_BOARD_GPIO_DESCRIPTION_GET) (
> +  IN MARVELL_BOARD_DESC_PROTOCOL    *This,
> +  IN OUT MV_BOARD_GPIO_DESCRIPTION **GpioDescription
> +  );
> +
> +typedef
> +EFI_STATUS
>  (EFIAPI *MV_BOARD_DESC_I2C_GET) (
>    IN MARVELL_BOARD_DESC_PROTOCOL  *This,
>    IN OUT MV_BOARD_I2C_DESC       **I2cDesc
> @@ -113,6 +120,7 @@ struct _MARVELL_BOARD_DESC_PROTOCOL {
>    MV_BOARD_DESC_UTMI_GET         BoardDescUtmiGet;
>    MV_BOARD_DESC_XHCI_GET         BoardDescXhciGet;
>    MV_BOARD_DESC_FREE             BoardDescFree;
> +  MV_BOARD_GPIO_DESCRIPTION_GET  GpioDescriptionGet;
>  };
>  
>  #endif // __MARVELL_BOARD_DESC_PROTOCOL_H__
> diff --git a/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c b/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c
> index f71bfc4..973c362 100644
> --- a/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c
> +++ b/Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c
> @@ -35,6 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>  
>  MV_BOARD_DESC *mBoardDescInstance;
>  
> +STATIC MV_BOARD_GPIO_DESCRIPTION *mGpioDescription;
> +
>  STATIC
>  EFI_STATUS
>  MvBoardDescComPhyGet (
> @@ -100,6 +102,53 @@ MvBoardDescComPhyGet (
>  
>  STATIC
>  EFI_STATUS
> +MvBoardGpioDescriptionGet (
> +  IN MARVELL_BOARD_DESC_PROTOCOL    *This,
> +  IN OUT MV_BOARD_GPIO_DESCRIPTION **GpioDescription
> +  )
> +{
> +  UINTN SoCGpioCount, GpioExpanderCount;
> +  MV_GPIO_EXPANDER *GpioExpanders;
> +  GPIO_CONTROLLER *SoCGpio;
> +  EFI_STATUS Status;
> +
> +  /* Use existing structure if already created. */
> +  if (mGpioDescription != NULL) {
> +    *GpioDescription = mGpioDescription;
> +    return EFI_SUCCESS;
> +  }
> +
> +  /* Get SoC data about all available GPIO controllers. */
> +  Status = ArmadaSoCGpioGet (&SoCGpio, &SoCGpioCount);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  /* Get per-board information about all available GPIO expanders. */
> +  Status = ArmadaBoardGpioExpanderGet (&GpioExpanders, &GpioExpanderCount);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  /* Allocate and fill board description. */
> +  mGpioDescription = AllocateZeroPool (sizeof (MV_BOARD_GPIO_DESCRIPTION));
> +  if (mGpioDescription == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Cannot allocate memory\n", __FUNCTION__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mGpioDescription->SoCGpio = SoCGpio;
> +  mGpioDescription->GpioDeviceCount = SoCGpioCount;
> +  mGpioDescription->GpioExpanders = GpioExpanders;
> +  mGpioDescription->GpioExpanderCount = GpioExpanderCount;
> +
> +  *GpioDescription = mGpioDescription;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
>  MvBoardDescI2cGet (
>    IN MARVELL_BOARD_DESC_PROTOCOL  *This,
>    IN OUT MV_BOARD_I2C_DESC       **I2cDesc
> @@ -571,6 +620,7 @@ MvBoardDescInitProtocol (
>    BoardDescProtocol->BoardDescUtmiGet = MvBoardDescUtmiGet;
>    BoardDescProtocol->BoardDescXhciGet = MvBoardDescXhciGet;
>    BoardDescProtocol->BoardDescFree = MvBoardDescFree;
> +  BoardDescProtocol->GpioDescriptionGet = MvBoardGpioDescriptionGet;
>  
>    return EFI_SUCCESS;
>  }
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 08/12] Marvell/Drivers: MvGpioDxe: Introduce platform GPIO driver
  2019-01-17 11:15 ` [platforms: PATCH v3 08/12] Marvell/Drivers: MvGpioDxe: Introduce platform GPIO driver Marcin Wojtas
@ 2019-01-17 11:52   ` Leif Lindholm
  0 siblings, 0 replies; 24+ messages in thread
From: Leif Lindholm @ 2019-01-17 11:52 UTC (permalink / raw)
  To: Marcin Wojtas; +Cc: edk2-devel, ard.biesheuvel, nadavh, jsd, jaz, kostap

On Thu, Jan 17, 2019 at 12:15:11PM +0100, Marcin Wojtas wrote:
> Marvell Armada 7k/8k SoCs comprise integrated GPIO controllers,
> one in AP806 and two in each south bridge hardware blocks.
> 
> This patch introduces support for them. The new driver implements
> a generic EMBEDDED_GPIO protocol.
> 
> In order to ease description of used GPIO pins and controllers
> of the Armada 7k8k platforms, add a common enum type.
> 
> Based on original work of Jing Hua <jinghua@marvell.com>.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Marcin Wojtas <mw@semihalf.com>

Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

> ---
>  Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf |  44 +++
>  Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h   |  49 +++
>  Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c   | 353 ++++++++++++++++++++
>  3 files changed, 446 insertions(+)
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c
> 
> diff --git a/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
> new file mode 100644
> index 0000000..5ff9130
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
> @@ -0,0 +1,44 @@
> +## @file
> +#
> +#  Copyright (c) 2017, Marvell International Ltd. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials are licensed and made available
> +#  under the terms and conditions of the BSD License which accompanies this
> +#  distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> +#  IMPLIED.
> +#
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001A
> +  BASE_NAME                      = MvGpioDxe
> +  FILE_GUID                      = 706eb761-b3b5-4f41-8558-5fd9217c0079
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = MvGpioEntryPoint
> +
> +[Sources]
> +  MvGpioDxe.c
> +  MvGpioDxe.h
> +
> +[Packages]
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Marvell/Marvell.dec
> +
> +[LibraryClasses]
> +  ArmadaSoCDescLib
> +  DebugLib
> +  MemoryAllocationLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Protocols]
> +  gEmbeddedGpioProtocolGuid
> +  gMarvellBoardDescProtocolGuid
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h
> new file mode 100644
> index 0000000..6e56ec1
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h
> @@ -0,0 +1,49 @@
> +/**
> +*
> +*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
> +*
> +*  This program and the accompanying materials are licensed and made available
> +*  under the terms and conditions of the BSD License which accompanies this
> +*  distribution. The full text of the license may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +#ifndef __MV_GPIO_H__
> +#define __MV_GPIO_H__
> +
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/MvGpioLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +#include <Protocol/BoardDesc.h>
> +
> +#include <Uefi/UefiBaseType.h>
> +
> +#define MV_GPIO_SIGNATURE        SIGNATURE_64 ('M', 'V','_','G', 'P', 'I','O',' ')
> +
> +// Marvell MV_GPIO Controller Registers
> +#define MV_GPIO_DATA_OUT_REG     (0x0)
> +#define MV_GPIO_OUT_EN_REG       (0x4)
> +#define MV_GPIO_BLINK_EN_REG     (0x8)
> +#define MV_GPIO_DATA_IN_POL_REG  (0xc)
> +#define MV_GPIO_DATA_IN_REG      (0x10)
> +
> +typedef struct {
> +  EMBEDDED_GPIO     GpioProtocol;
> +  GPIO_CONTROLLER  *SoCGpio;
> +  UINTN             GpioDeviceCount;
> +  UINTN             Signature;
> +  EFI_HANDLE        Handle;
> +} MV_GPIO;
> +
> +#endif // __MV_GPIO_H__
> diff --git a/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c
> new file mode 100644
> index 0000000..1d37ecc
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c
> @@ -0,0 +1,353 @@
> +/**
> +*
> +*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
> +*
> +*  This program and the accompanying materials are licensed and made available
> +*  under the terms and conditions of the BSD License which accompanies this
> +*  distribution. The full text of the license may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +
> +#include "MvGpioDxe.h"
> +
> +STATIC MV_GPIO *mGpioInstance;
> +
> +STATIC MV_GPIO_DEVICE_PATH mDevicePathTemplate = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8) (sizeof (VENDOR_DEVICE_PATH) +
> +                 sizeof (MV_GPIO_DRIVER_TYPE)),
> +        (UINT8) ((sizeof (VENDOR_DEVICE_PATH) +
> +                 sizeof (MV_GPIO_DRIVER_TYPE)) >> 8),
> +      },
> +    },
> +    EFI_CALLER_ID_GUID
> +  },
> +  MV_GPIO_DRIVER_TYPE_SOC_CONTROLLER,
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      sizeof(EFI_DEVICE_PATH_PROTOCOL),
> +      0
> +    }
> +  }
> +};
> +
> +#if !defined(MDEPKG_NDEBUG)
> +/**
> +
> +Routine Description:
> +
> +  Verifies if controller index / GPIO pin values
> +  are within proper boundaries.
> +
> +Arguments:
> +
> +  ControllerIndex - index of controller
> +  GpioPin - which pin to read
> +
> +Returns:
> +
> +  EFI_SUCCESS           - GPIO pin / controller index are proper
> +  EFI_INVALID_PARAMETER - GPIO pin / controller index is out of range
> +**/
> +STATIC
> +EFI_STATUS
> +MvGpioValidate (
> +  IN UINTN ControllerIndex,
> +  IN UINTN GpioPin
> +  )
> +{
> +  if (ControllerIndex >= mGpioInstance->GpioDeviceCount) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Invalid GPIO ControllerIndex: %d\n",
> +      __FUNCTION__,
> +      ControllerIndex));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (GpioPin >= mGpioInstance->SoCGpio[ControllerIndex].InternalGpioCount) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: GPIO pin #%d not available in Controller#%d\n",
> +      __FUNCTION__,
> +      GpioPin,
> +      ControllerIndex));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +#endif
> +
> +/**
> +
> +Routine Description:
> +
> +  Gets the mode (function) of a GPIO pin
> +
> +Arguments:
> +
> +  This  - pointer to protocol
> +  Gpio  - which pin
> +  Mode  - pointer to output mode value
> +
> +Returns:
> +
> +  EFI_SUCCESS           - mode value retrieved
> +  EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range
> +
> +**/
> +STATIC
> +EFI_STATUS
> +MvGpioGetMode (
> +  IN  EMBEDDED_GPIO       *This,
> +  IN  EMBEDDED_GPIO_PIN    Gpio,
> +  OUT EMBEDDED_GPIO_MODE  *Mode
> +  )
> +{
> +  UINTN ControllerIndex;
> +  UINTN BaseAddress;
> +  UINTN GpioPin;
> +
> +  GpioPin = GPIO_PIN (Gpio);
> +  ControllerIndex = GPIO_PORT (Gpio);
> +
> +  ASSERT_EFI_ERROR (MvGpioValidate (ControllerIndex, GpioPin));
> +
> +  BaseAddress = mGpioInstance->SoCGpio[ControllerIndex].RegisterBase;
> +
> +  if (MmioRead32 (BaseAddress + MV_GPIO_OUT_EN_REG) & (1 << GpioPin)) {
> +    *Mode = GPIO_MODE_INPUT;
> +  } else {
> +    if (MmioRead32 (BaseAddress + MV_GPIO_DATA_IN_REG) & (1 << GpioPin)) {
> +      *Mode = GPIO_MODE_OUTPUT_1;
> +    } else {
> +      *Mode = GPIO_MODE_OUTPUT_0;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +Routine Description:
> +
> +  Gets the state of a GPIO pin
> +
> +Arguments:
> +
> +  This  - pointer to protocol
> +  Gpio  - which pin to read
> +  Value - state of the pin
> +
> +Returns:
> +
> +  EFI_SUCCESS           - GPIO state returned in Value
> +  EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range
> +**/
> +STATIC
> +EFI_STATUS
> +MvGpioGet (
> +  IN  EMBEDDED_GPIO      *This,
> +  IN  EMBEDDED_GPIO_PIN   Gpio,
> +  OUT UINTN              *Value
> +  )
> +{
> +  UINTN ControllerIndex;
> +  UINTN BaseAddress;
> +  UINTN GpioPin;
> +
> +  GpioPin = GPIO_PIN (Gpio);
> +  ControllerIndex = GPIO_PORT (Gpio);
> +
> +  ASSERT_EFI_ERROR (MvGpioValidate (ControllerIndex, GpioPin));
> +
> +  BaseAddress = mGpioInstance->SoCGpio[ControllerIndex].RegisterBase;
> +
> +  if (MmioRead32 (BaseAddress + MV_GPIO_DATA_IN_REG) & (1 << GpioPin)) {
> +    *Value = 1;
> +  } else {
> +    *Value = 0;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +Routine Description:
> +
> +  Sets the state of a GPIO pin
> +
> +Arguments:
> +
> +  This  - pointer to protocol
> +  Gpio  - which pin to modify
> +  Mode  - mode to set
> +
> +Returns:
> +
> +  EFI_SUCCESS           - GPIO set as requested
> +  EFI_UNSUPPORTED       - Mode is not supported
> +  EFI_INVALID_PARAMETER - Gpio pin is out of range
> +**/
> +STATIC
> +EFI_STATUS
> +MvGpioSet (
> +  IN EMBEDDED_GPIO       *This,
> +  IN EMBEDDED_GPIO_PIN    Gpio,
> +  IN EMBEDDED_GPIO_MODE   Mode
> +  )
> +{
> +  UINTN ControllerIndex;
> +  UINTN BaseAddress;
> +  UINTN GpioPin;
> +
> +  GpioPin = GPIO_PIN (Gpio);
> +  ControllerIndex = GPIO_PORT (Gpio);
> +
> +  ASSERT_EFI_ERROR (MvGpioValidate (ControllerIndex, GpioPin));
> +
> +  BaseAddress = mGpioInstance->SoCGpio[ControllerIndex].RegisterBase;
> +
> +  switch (Mode) {
> +  case GPIO_MODE_OUTPUT_0:
> +    MmioAnd32 (BaseAddress + MV_GPIO_DATA_OUT_REG, ~(1 << GpioPin));
> +    MmioAnd32 (BaseAddress + MV_GPIO_OUT_EN_REG, ~(1 << GpioPin));
> +    break;
> +
> +  case GPIO_MODE_OUTPUT_1:
> +    MmioOr32 (BaseAddress + MV_GPIO_DATA_OUT_REG, (1 << GpioPin));
> +    MmioAnd32 (BaseAddress + MV_GPIO_OUT_EN_REG, ~(1 << GpioPin));
> +    break;
> +
> +  case GPIO_MODE_INPUT:
> +    MmioOr32 (BaseAddress + MV_GPIO_OUT_EN_REG, (1 << GpioPin));
> +    break;
> +
> +  default:
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +Routine Description:
> +
> +  Sets the pull-up / pull-down resistor of a GPIO pin
> +
> +Arguments:
> +
> +  This  - pointer to protocol
> +  Gpio  - which pin
> +  Direction - pull-up, pull-down, or none
> +
> +Returns:
> +
> +  EFI_UNSUPPORTED - Can not perform the requested operation
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MvGpioSetPull (
> +  IN  EMBEDDED_GPIO       *This,
> +  IN  EMBEDDED_GPIO_PIN   Gpio,
> +  IN  EMBEDDED_GPIO_PULL  Direction
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +STATIC
> +VOID
> +MvGpioInitProtocol (
> +  IN EMBEDDED_GPIO *GpioProtocol
> +  )
> +{
> +  GpioProtocol->Get     = MvGpioGet;
> +  GpioProtocol->Set     = MvGpioSet;
> +  GpioProtocol->GetMode = MvGpioGetMode;
> +  GpioProtocol->SetPull = MvGpioSetPull;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +MvGpioEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  MARVELL_BOARD_DESC_PROTOCOL *MvBoardProtocol;
> +  MV_BOARD_GPIO_DESCRIPTION *GpioDescription;
> +  MV_GPIO_DEVICE_PATH *GpioDevicePath;
> +  EFI_STATUS Status;
> +
> +  GpioDevicePath = AllocateCopyPool (sizeof (MV_GPIO_DEVICE_PATH),
> +                     &mDevicePathTemplate);
> +  if (GpioDevicePath == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mGpioInstance = AllocateZeroPool (sizeof (MV_GPIO));
> +  if (mGpioInstance == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrGpioInstanceAlloc;
> +  }
> +
> +  /* Obtain list of available controllers */
> +  Status = gBS->LocateProtocol (&gMarvellBoardDescProtocolGuid,
> +                  NULL,
> +                  (VOID **)&MvBoardProtocol);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Cannot locate BoardDesc protocol\n",
> +      __FUNCTION__));
> +    goto ErrLocateBoardDesc;
> +  }
> +
> +  Status = MvBoardProtocol->GpioDescriptionGet (MvBoardProtocol,
> +             &GpioDescription);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Cannot get GPIO board desc from BoardDesc protocol\n",
> +      __FUNCTION__));
> +    goto ErrLocateBoardDesc;
> +  }
> +
> +  mGpioInstance->Signature = MV_GPIO_SIGNATURE;
> +  mGpioInstance->GpioDeviceCount = GpioDescription->GpioDeviceCount;
> +  mGpioInstance->SoCGpio = GpioDescription->SoCGpio;
> +
> +  MvGpioInitProtocol (&mGpioInstance->GpioProtocol);
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (&(mGpioInstance->Handle),
> +                  &gEmbeddedGpioProtocolGuid,
> +                  &(mGpioInstance->GpioProtocol),
> +                  &gEfiDevicePathProtocolGuid,
> +                  (EFI_DEVICE_PATH_PROTOCOL *)GpioDevicePath,
> +                  NULL);
> +  if (EFI_ERROR (Status)) {
> +    goto ErrLocateBoardDesc;
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +ErrLocateBoardDesc:
> +  gBS->FreePool (mGpioInstance);
> +
> +ErrGpioInstanceAlloc:
> +  gBS->FreePool (GpioDevicePath);
> +
> +  return Status;
> +}
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 10/12] Marvell/Drivers: MvPca95xxDxe: Introduce GPIO expander driver
  2019-01-17 11:15 ` [platforms: PATCH v3 10/12] Marvell/Drivers: MvPca95xxDxe: Introduce GPIO expander driver Marcin Wojtas
@ 2019-01-17 11:55   ` Leif Lindholm
  0 siblings, 0 replies; 24+ messages in thread
From: Leif Lindholm @ 2019-01-17 11:55 UTC (permalink / raw)
  To: Marcin Wojtas; +Cc: edk2-devel, ard.biesheuvel, nadavh, jsd, jaz, kostap

On Thu, Jan 17, 2019 at 12:15:13PM +0100, Marcin Wojtas wrote:
> Marvell Armada 7k/8k-based platforms may use Pca95xx to extend
> amount of the GPIO pins.
> 
> This patch introduces support for them. The new driver implements
> a generic EMBEDDED_GPIO protocol.
> 
> In order to ease description of used PCA9XXX controllers
> add a common enum type. It can be used e.g. in the board description
> library to specify the expander model on a board (instead of passing
> a raw number). Update relevant libraries.
> 
> Driver is based on initial work done by Allen Yan <yanwei@marvell.com>.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Marcin Wojtas <mw@semihalf.com>

Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

> ---
>  Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf |  45 ++
>  Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h   |  65 ++
>  Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c   | 645 ++++++++++++++++++++
>  3 files changed, 755 insertions(+)
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c
> 
> diff --git a/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
> new file mode 100644
> index 0000000..3b1ab4e
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
> @@ -0,0 +1,45 @@
> +## @file
> +#
> +#  Copyright (c) 2017, Marvell International Ltd. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials are licensed and made available
> +#  under the terms and conditions of the BSD License which accompanies this
> +#  distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> +#  IMPLIED.
> +#
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001A
> +  BASE_NAME                      = MvPca95xxDxe
> +  FILE_GUID                      = f0e405eb-8407-43b9-88e6-2f7d70715c72
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = MvPca95xxEntryPoint
> +
> +[Sources]
> +  MvPca95xxDxe.c
> +  MvPca95xxDxe.h
> +
> +[Packages]
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Marvell/Marvell.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +  MemoryAllocationLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Protocols]
> +  gEfiDriverBindingProtocolGuid
> +  gEfiI2cIoProtocolGuid
> +  gEmbeddedGpioProtocolGuid
> +  gMarvellBoardDescProtocolGuid
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h
> new file mode 100644
> index 0000000..29eb123
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h
> @@ -0,0 +1,65 @@
> +/**
> +*
> +*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
> +*
> +*  This program and the accompanying materials are licensed and made available
> +*  under the terms and conditions of the BSD License which accompanies this
> +*  distribution. The full text of the license may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +#ifndef __MV_PCA953X_H__
> +#define __MV_PCA953X_H__
> +
> +#include <Library/ArmadaBoardDescLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/MvGpioLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +#include <Protocol/BoardDesc.h>
> +#include <Protocol/MvI2c.h>
> +
> +#include <Uefi/UefiBaseType.h>
> +
> +#define PCA95XX_GPIO_SIGNATURE   SIGNATURE_32 ('I', 'O', 'E', 'X')
> +
> +#define PCA95XX_INPUT_REG        0x0
> +#define PCA95XX_OUTPUT_REG       0x2
> +#define PCA95XX_DIRECTION_REG    0x6
> +
> +#define PCA95XX_BANK_SIZE        8
> +#define PCA95XX_OPERATION_COUNT  2
> +#define PCA95XX_OPERATION_LENGTH 1
> +
> +typedef enum {
> +  PCA9505_PIN_COUNT = 40,
> +  PCA9534_PIN_COUNT = 8,
> +  PCA9535_PIN_COUNT = 16,
> +  PCA9536_PIN_COUNT = 4,
> +  PCA9537_PIN_COUNT = 4,
> +  PCA9538_PIN_COUNT = 8,
> +  PCA9539_PIN_COUNT = 16,
> +  PCA9554_PIN_COUNT = 8,
> +  PCA9555_PIN_COUNT = 16,
> +  PCA9556_PIN_COUNT = 16,
> +  PCA9557_PIN_COUNT = 16,
> +} PCA95XX_PIN_COUNT;
> +
> +typedef struct {
> +  EMBEDDED_GPIO      GpioProtocol;
> +  MV_GPIO_EXPANDER  *GpioExpanders;
> +  UINTN              GpioExpanderCount;
> +  UINTN              Signature;
> +  EFI_HANDLE         ControllerHandle;
> +} PCA95XX;
> +
> +#endif
> diff --git a/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c
> new file mode 100644
> index 0000000..8e7ea77
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c
> @@ -0,0 +1,645 @@
> +/**
> +*
> +*  Copyright (c) 2018, Marvell International Ltd. All rights reserved.
> +*
> +*  This program and the accompanying materials are licensed and made available
> +*  under the terms and conditions of the BSD License which accompanies this
> +*  distribution. The full text of the license may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +
> +#include <Protocol/I2cIo.h>
> +
> +#include <Pi/PiI2c.h>
> +
> +#include "MvPca95xxDxe.h"
> +
> +STATIC PCA95XX *mPca95xxInstance;
> +
> +STATIC MV_GPIO_DEVICE_PATH mDevicePathTemplate = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8) (sizeof (VENDOR_DEVICE_PATH) +
> +                 sizeof (MV_GPIO_DRIVER_TYPE)),
> +        (UINT8) ((sizeof (VENDOR_DEVICE_PATH) +
> +                 sizeof (MV_GPIO_DRIVER_TYPE)) >> 8),
> +      },
> +    },
> +    EFI_CALLER_ID_GUID
> +  },
> +  MV_GPIO_DRIVER_TYPE_PCA95XX,
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      sizeof(EFI_DEVICE_PATH_PROTOCOL),
> +      0
> +    }
> +  }
> +};
> +
> +STATIC PCA95XX_PIN_COUNT mPca95xxPinCount[PCA95XX_MAX_ID] = {
> +  PCA9505_PIN_COUNT,
> +  PCA9534_PIN_COUNT,
> +  PCA9535_PIN_COUNT,
> +  PCA9536_PIN_COUNT,
> +  PCA9537_PIN_COUNT,
> +  PCA9538_PIN_COUNT,
> +  PCA9539_PIN_COUNT,
> +  PCA9554_PIN_COUNT,
> +  PCA9555_PIN_COUNT,
> +  PCA9556_PIN_COUNT,
> +  PCA9557_PIN_COUNT,
> +};
> +
> +#if !defined(MDEPKG_NDEBUG)
> +/**
> +
> +Routine Description:
> +
> +  Verifies if controller index / GPIO pin values
> +  are within proper boundaries.
> +
> +Arguments:
> +
> +  ControllerIndex - index of controller
> +  GpioPin - which pin to read
> +
> +Returns:
> +
> +  EFI_SUCCESS           - GPIO pin / controller index are proper
> +  EFI_INVALID_PARAMETER - GPIO pin / controller index is out of range
> +**/
> +STATIC
> +EFI_STATUS
> +MvPca95xxValidate (
> +  IN UINTN ControllerIndex,
> +  IN UINTN GpioPin
> +  )
> +{
> +  UINTN ControllerId;
> +
> +  if (ControllerIndex >= mPca95xxInstance->GpioExpanderCount) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Invalid GPIO ControllerIndex: %d\n",
> +      __FUNCTION__,
> +      ControllerIndex));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  ControllerId = mPca95xxInstance->GpioExpanders[ControllerIndex].ChipId;
> +
> +  if (GpioPin >= mPca95xxPinCount[ControllerId]) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: GPIO pin #%d not available in Controller#%d\n",
> +      __FUNCTION__,
> +      GpioPin,
> +      ControllerIndex));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +#endif
> +
> +EFI_STATUS
> +EFIAPI
> +MvPca95xxGetI2c (
> +  IN     UINTN                 ControllerIndex,
> +  IN OUT EFI_I2C_IO_PROTOCOL **I2cIo
> +  )
> +{
> +  UINTN        I2cBus, I2cAddress;
> +  UINTN        HandleCount, Index;
> +  EFI_HANDLE  *HandleBuffer;
> +  EFI_STATUS   Status;
> +
> +  I2cBus = mPca95xxInstance->GpioExpanders[ControllerIndex].I2cBus;
> +  I2cAddress = mPca95xxInstance->GpioExpanders[ControllerIndex].I2cAddress;
> +
> +  /* Locate Handles of all EfiI2cIoProtocol producers */
> +  Status = gBS->LocateHandleBuffer (ByProtocol,
> +                  &gEfiI2cIoProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Unable to locate handles\n", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  /* Iterate over all protocol producers and pick one upon DeviceIndex match */
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    Status = gBS->OpenProtocol (HandleBuffer[Index],
> +                    &gEfiI2cIoProtocolGuid,
> +                    (VOID **)I2cIo,
> +                    gImageHandle,
> +                    NULL,
> +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a: Unable to open protocol\n", __FUNCTION__));
> +      gBS->FreePool (HandleBuffer);
> +      return Status;
> +    }
> +    if ((*I2cIo)->DeviceIndex == I2C_DEVICE_INDEX (I2cBus, I2cAddress)) {
> +      gBS->FreePool (HandleBuffer);
> +      return EFI_SUCCESS;
> +    }
> +  }
> +
> +  gBS->FreePool (HandleBuffer);
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +MvPca95xxI2cTransfer (
> +  IN EFI_I2C_IO_PROTOCOL *I2cIo,
> +  IN UINT8                Address,
> +  IN UINT8               *Buffer,
> +  IN UINT32               Flag
> +  )
> +{
> +  EFI_I2C_REQUEST_PACKET *RequestPacket;
> +  UINTN RequestPacketSize;
> +  UINT8 AddressBuffer;
> +  EFI_STATUS Status;
> +
> +  RequestPacketSize = sizeof (UINTN) +
> +                      sizeof (EFI_I2C_OPERATION) * PCA95XX_OPERATION_COUNT;
> +  RequestPacket = AllocateZeroPool (RequestPacketSize);
> +  if (RequestPacket == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  /* Operations contain address and payload, consecutively. */
> +  RequestPacket->OperationCount = PCA95XX_OPERATION_COUNT;
> +  RequestPacket->Operation[0].LengthInBytes = PCA95XX_OPERATION_LENGTH;
> +  RequestPacket->Operation[0].Buffer = &AddressBuffer;
> +  RequestPacket->Operation[0].Buffer[0] = Address & MAX_UINT8;
> +  RequestPacket->Operation[1].LengthInBytes = PCA95XX_OPERATION_LENGTH;
> +  RequestPacket->Operation[1].Buffer = Buffer;
> +  RequestPacket->Operation[1].Flags = Flag;
> +
> +  Status = I2cIo->QueueRequest (I2cIo, 0, NULL, RequestPacket, NULL);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: transmission error: 0x%d\n",
> +      __FUNCTION__,
> +      Status));
> +  }
> +
> +  gBS->FreePool(RequestPacket);
> +
> +  return Status;
> +}
> +
> +STATIC
> +EFI_STATUS
> +MvPca95xxReadRegs (
> +  IN  EFI_I2C_IO_PROTOCOL *I2cIo,
> +  IN  UINT8                Reg,
> +  OUT UINT8               *RegVal
> +  )
> +{
> +  return MvPca95xxI2cTransfer (I2cIo, Reg, RegVal, I2C_FLAG_READ);
> +}
> +
> +STATIC
> +EFI_STATUS
> +MvPca95xxWriteRegs (
> +  IN  EFI_I2C_IO_PROTOCOL *I2cIo,
> +  IN  UINTN                Reg,
> +  IN  UINT8                RegVal
> +  )
> +{
> +  return MvPca95xxI2cTransfer (I2cIo, Reg, &RegVal, I2C_FLAG_NORESTART);
> +}
> +
> +STATIC
> +EFI_STATUS
> +MvPca95xxSetOutputValue (
> +  IN UINTN               ControllerIndex,
> +  IN UINTN               GpioPin,
> +  IN EMBEDDED_GPIO_MODE  Mode
> +  )
> +{
> +  EFI_I2C_IO_PROTOCOL *I2cIo;
> +  EFI_STATUS Status;
> +  UINT8 RegVal;
> +  UINTN Bank;
> +
> +  Status = MvPca95xxGetI2c (ControllerIndex, &I2cIo);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: fail to get I2C protocol\n", __FUNCTION__));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  Bank = GpioPin / PCA95XX_BANK_SIZE;
> +
> +  Status = MvPca95xxReadRegs (I2cIo, PCA95XX_OUTPUT_REG + Bank, &RegVal);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: fail to read device register\n", __FUNCTION__));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (Mode == GPIO_MODE_OUTPUT_1) {
> +    RegVal |= (1 << (GpioPin % PCA95XX_BANK_SIZE));
> +  } else {
> +    RegVal &= ~(1 << (GpioPin % PCA95XX_BANK_SIZE));
> +  }
> +
> +  Status = MvPca95xxWriteRegs (I2cIo, PCA95XX_OUTPUT_REG + Bank, RegVal);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: fail to write device register\n", __FUNCTION__));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +MvPca95xxSetDirection (
> +  IN UINTN              ControllerIndex,
> +  IN UINTN              GpioPin,
> +  IN EMBEDDED_GPIO_MODE Mode
> +  )
> +{
> +  EFI_I2C_IO_PROTOCOL *I2cIo;
> +  EFI_STATUS Status;
> +  UINT8 RegVal;
> +  UINTN Bank;
> +
> +  Status = MvPca95xxGetI2c (ControllerIndex, &I2cIo);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: fail to get I2C protocol\n", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  Bank = GpioPin / PCA95XX_BANK_SIZE;
> +
> +  Status = MvPca95xxReadRegs (I2cIo, PCA95XX_DIRECTION_REG + Bank, &RegVal);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: fail to read device register\n", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  if (Mode == GPIO_MODE_INPUT) {
> +    RegVal |= (1 << (GpioPin % PCA95XX_BANK_SIZE));
> +  } else {
> +    RegVal &= ~(1 << (GpioPin % PCA95XX_BANK_SIZE));
> +  }
> +
> +  Status = MvPca95xxWriteRegs (I2cIo, PCA95XX_DIRECTION_REG + Bank, RegVal);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: fail to write device register\n", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +MvPca95xxReadMode (
> +  IN  UINTN               ControllerIndex,
> +  IN  UINTN               GpioPin,
> +  OUT EMBEDDED_GPIO_MODE *Mode
> +  )
> +{
> +  EFI_I2C_IO_PROTOCOL *I2cIo;
> +  EFI_STATUS Status;
> +  UINT8 RegVal;
> +  UINTN Bank;
> +
> +  ASSERT_EFI_ERROR (MvPca95xxValidate (ControllerIndex, GpioPin));
> +
> +  Status = MvPca95xxGetI2c (ControllerIndex, &I2cIo);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: fail to get I2C protocol\n", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  Bank = GpioPin / PCA95XX_BANK_SIZE;
> +
> +  Status = MvPca95xxReadRegs (I2cIo, PCA95XX_DIRECTION_REG + Bank, &RegVal);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: fail to read device register\n", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  if (RegVal & (1 << (GpioPin % PCA95XX_BANK_SIZE))) {
> +    *Mode = GPIO_MODE_INPUT;
> +  } else {
> +    Status = MvPca95xxReadRegs (I2cIo, PCA95XX_INPUT_REG + Bank, &RegVal);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a: fail to read device register\n", __FUNCTION__));
> +      return Status;
> +    }
> +
> +    if (RegVal & (1 << (GpioPin % PCA95XX_BANK_SIZE))) {
> +      *Mode = GPIO_MODE_OUTPUT_1;
> +    } else {
> +      *Mode = GPIO_MODE_OUTPUT_0;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +Routine Description:
> +
> +  Gets the mode (function) of a GPIO pin
> +
> +Arguments:
> +
> +  This  - pointer to protocol
> +  Gpio  - which pin
> +  Mode  - pointer to output mode value
> +
> +Returns:
> +
> +  EFI_SUCCESS           - mode value retrieved
> +  EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range
> +
> +**/
> +STATIC
> +EFI_STATUS
> +MvPca95xxGetMode (
> +  IN  EMBEDDED_GPIO       *This,
> +  IN  EMBEDDED_GPIO_PIN    Gpio,
> +  OUT EMBEDDED_GPIO_MODE  *Mode
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINTN ControllerIndex;
> +  UINTN GpioPin;
> +
> +  GpioPin = GPIO_PIN (Gpio);
> +  ControllerIndex = GPIO_PORT (Gpio);
> +
> +  ASSERT_EFI_ERROR (MvPca95xxValidate (ControllerIndex, GpioPin));
> +
> +  Status = MvPca95xxReadMode (ControllerIndex, GpioPin, Mode);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: fail to get pin %d of controller#%d mode\n",
> +      __FUNCTION__,
> +      GpioPin,
> +      ControllerIndex));
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +
> +Routine Description:
> +
> +  Gets the state of a GPIO pin
> +
> +Arguments:
> +
> +  This  - pointer to protocol
> +  Gpio  - which pin to read
> +  Value - state of the pin
> +
> +Returns:
> +
> +  EFI_SUCCESS           - GPIO state returned in Value
> +  EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range
> +**/
> +STATIC
> +EFI_STATUS
> +MvPca95xxGet (
> +  IN  EMBEDDED_GPIO      *This,
> +  IN  EMBEDDED_GPIO_PIN   Gpio,
> +  OUT UINTN              *Value
> +  )
> +{
> +  EFI_I2C_IO_PROTOCOL *I2cIo;
> +  EFI_STATUS Status;
> +  UINTN ControllerIndex;
> +  UINTN GpioPin;
> +  UINT8 RegVal;
> +  UINTN Bank;
> +
> +  GpioPin = GPIO_PIN (Gpio);
> +  ControllerIndex = GPIO_PORT (Gpio);
> +
> +  ASSERT_EFI_ERROR (MvPca95xxValidate (ControllerIndex, GpioPin));
> +
> +  Status = MvPca95xxGetI2c (ControllerIndex, &I2cIo);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: fail to get I2C protocol\n", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  Bank = GpioPin / PCA95XX_BANK_SIZE;
> +
> +  Status = MvPca95xxReadRegs (I2cIo, PCA95XX_INPUT_REG + Bank, &RegVal);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: fail to read device register\n", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  if (RegVal & (1 << (GpioPin % PCA95XX_BANK_SIZE))) {
> +    *Value = 1;
> +  } else {
> +    *Value = 0;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +Routine Description:
> +
> +  Sets the state of a GPIO pin
> +
> +Arguments:
> +
> +  This  - pointer to protocol
> +  Gpio  - which pin to modify
> +  Mode  - mode to set
> +
> +Returns:
> +
> +  EFI_SUCCESS           - GPIO set as requested
> +  EFI_UNSUPPORTED       - Mode is not supported
> +  EFI_INVALID_PARAMETER - Gpio pin is out of range
> +**/
> +STATIC
> +EFI_STATUS
> +MvPca95xxSet (
> +  IN EMBEDDED_GPIO       *This,
> +  IN EMBEDDED_GPIO_PIN   Gpio,
> +  IN EMBEDDED_GPIO_MODE  Mode
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINTN ControllerIndex;
> +  UINTN GpioPin;
> +
> +  GpioPin = GPIO_PIN (Gpio);
> +  ControllerIndex = GPIO_PORT (Gpio);
> +
> +  ASSERT_EFI_ERROR (MvPca95xxValidate (ControllerIndex, GpioPin));
> +
> +  switch (Mode) {
> +  case GPIO_MODE_OUTPUT_0:
> +  case GPIO_MODE_OUTPUT_1:
> +    Status = MvPca95xxSetOutputValue (ControllerIndex, GpioPin, Mode);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a: fail to set ouput value\n", __FUNCTION__));
> +      return Status;
> +    }
> +
> +  /* Fall-through */
> +  case GPIO_MODE_INPUT:
> +    Status = MvPca95xxSetDirection (ControllerIndex, GpioPin, Mode);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a: fail to set direction\n", __FUNCTION__));
> +      return Status;
> +    }
> +    break;
> +
> +  default:
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +Routine Description:
> +
> +  Sets the pull-up / pull-down resistor of a GPIO pin
> +
> +Arguments:
> +
> +  This  - pointer to protocol
> +  Gpio  - which pin
> +  Direction - pull-up, pull-down, or none
> +
> +Returns:
> +
> +  EFI_UNSUPPORTED - Can not perform the requested operation
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MvPca95xxSetPull (
> +  IN EMBEDDED_GPIO       *This,
> +  IN EMBEDDED_GPIO_PIN   Gpio,
> +  IN EMBEDDED_GPIO_PULL  Direction
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +STATIC
> +VOID
> +MvPca95xxInitProtocol (
> +  IN EMBEDDED_GPIO *GpioProtocol
> +  )
> +{
> +  GpioProtocol->Get     = MvPca95xxGet;
> +  GpioProtocol->Set     = MvPca95xxSet;
> +  GpioProtocol->GetMode = MvPca95xxGetMode;
> +  GpioProtocol->SetPull = MvPca95xxSetPull;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +MvPca95xxEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  MARVELL_BOARD_DESC_PROTOCOL *MvBoardProtocol;
> +  MV_BOARD_GPIO_DESCRIPTION *GpioDescription;
> +  MV_GPIO_DEVICE_PATH *Pca95xxDevicePath;
> +  EFI_STATUS Status;
> +
> +  /* Obtain list of available controllers */
> +  Status = gBS->LocateProtocol (&gMarvellBoardDescProtocolGuid,
> +                  NULL,
> +                  (VOID **)&MvBoardProtocol);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Cannot locate BoardDesc protocol\n",
> +      __FUNCTION__));
> +    return Status;
> +  }
> +
> +  Status = MvBoardProtocol->GpioDescriptionGet (MvBoardProtocol,
> +             &GpioDescription);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Cannot get GPIO board desc from BoardDesc protocol\n",
> +      __FUNCTION__));
> +    return Status;
> +  } else if (GpioDescription->GpioExpanders == NULL) {
> +    /* Silently exit, if the board does not support the controllers */
> +    return EFI_SUCCESS;
> +  }
> +
> +  Pca95xxDevicePath = AllocateCopyPool (sizeof (MV_GPIO_DEVICE_PATH),
> +                        &mDevicePathTemplate);
> +  if (Pca95xxDevicePath == NULL) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Fail to allocate Pca95xxDevicePath\n",
> +      __FUNCTION__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPca95xxInstance = AllocateZeroPool (sizeof (PCA95XX));
> +  if (mPca95xxInstance == NULL) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Fail to allocate mPca95xxInstance\n",
> +      __FUNCTION__));
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrPca95xxInstanceAlloc;
> +  }
> +
> +  MvPca95xxInitProtocol (&mPca95xxInstance->GpioProtocol);
> +
> +  mPca95xxInstance->Signature = PCA95XX_GPIO_SIGNATURE;
> +  mPca95xxInstance->GpioExpanders = GpioDescription->GpioExpanders;
> +  mPca95xxInstance->GpioExpanderCount = GpioDescription->GpioExpanderCount;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &(mPca95xxInstance->ControllerHandle),
> +                  &gEmbeddedGpioProtocolGuid,
> +                  &(mPca95xxInstance->GpioProtocol),
> +                  &gEfiDevicePathProtocolGuid,
> +                  (EFI_DEVICE_PATH_PROTOCOL *)Pca95xxDevicePath,
> +                  NULL);
> +  if (EFI_ERROR (Status)) {
> +    goto ErrInstallProtocols;
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +ErrInstallProtocols:
> +  gBS->FreePool (mPca95xxInstance);
> +
> +ErrPca95xxInstanceAlloc:
> +  gBS->FreePool (Pca95xxDevicePath);
> +
> +  return Status;
> +}
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 00/12] Armada 7k8k GPIO support
  2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
                   ` (11 preceding siblings ...)
  2019-01-17 11:15 ` [platforms: PATCH v3 12/12] Marvell/Armada7k8k: Introduce NonDiscoverable device init routines Marcin Wojtas
@ 2019-01-17 12:03 ` Leif Lindholm
  2019-01-17 12:26   ` Marcin Wojtas
  12 siblings, 1 reply; 24+ messages in thread
From: Leif Lindholm @ 2019-01-17 12:03 UTC (permalink / raw)
  To: Marcin Wojtas; +Cc: edk2-devel, ard.biesheuvel, nadavh, jsd, jaz, kostap

So, I was about to say that apart from the "class" to be deleted from
3/12 subject line, things were fine so I was going to fix that locally
and push.

However. 3/12 is missing the Contributed-under tag.
Can you please separately confirm that it is intended to be
contributed under TianoCore Contribution Agreement 1.1?

/                                                                                                                 Leif

On Thu, Jan 17, 2019 at 12:15:03PM +0100, Marcin Wojtas wrote:
> Hi,
> 
> I submit v3 of the GPIO patchset for the Marvell SoCs.
> The changes are not significant and they address all the comments
> from the previous version. Please find the details in the changelog
> below.
> 
> Patches are available in the github:
> https://github.com/MarvellEmbeddedProcessors/edk2-open-platform/commits/gpio-upstream-r20190117
> 
> I am looking forward to your feedback.
> 
> Best regards,
> Marcin
> 
> Changelog:
> v2->v3:
> * 1,2,4,12/12
>    - Add Leif's RB  
> 
> * 3/12
>   - Change MvGpio.h to be library header (Library/MvGpioLib.h)
>   - Introduce MvGpioLib library
>   - Add PCA_ID enums in this patch (instead from PCA9xxx addition)
> 
> * 5,6/12
>   - Use PCA_ID enum from the beginning
> 
> * 7/12
>   - Use static global variable and allocate it only only once
>   - s/I2C/GPIO/
> 
> * 8/12
>   - Simplify error path after changing approach to not freeing
>     already allocated GpioDescription in MvBoardDescDxe
>   - Change signature to non-generic
> 
> * 10/12
>   - Simplify error path after changing approach to not freeing
>     already allocated GpioDescription in MvBoardDescDxe
>   - No need to update PCA_ID in this patch
> 
> v1->v2:
> * All
>   - rebase on top of the master branch and Xenon changes
> 
> * 1/12
>   - s/AP/AP806/ in order to avoid confusion
>   - drop desc/DESC usage and improve variables naming
>   - use GPIO_CONTROLLER from EmbeddedGpio.h instead of custom MV_SOC_GPIO
>   - update commit message
> 
> * 2,3,4,5/12
>   - drop desc/DESC usage and improve variables naming
>   - drop reference to I2c and use GpioExpander
>   - improve commit logs
> 
> * 6/12
>   - drop desc/DESC usage and improve variables naming
>   - drop reference to I2c and use GpioExpander
>   - remove global variable - same as for other interfaces the consumer
>     is responsible for avoiding memory leak
> 
> * 7/12
>   - use MV_GPIO_ prefix
>   - switch to EMBEDDED_GPIO
>   - remove custom Marvell GPIO Protocol and types
>   - add subroutine to MvGpioGetProtocol and more coments to clarify the code
>   - add driver types and related enums in other commits
> 
> * 8/12
>   - extend error path in the entry point, rename variables
>   - use MV_GPIO_ prefix
>   - switch to EMBEDDED_GPIO
>   - remove custom Marvell GPIO Protocol and types
>   - replace '!!' expression for obtaining pin state
>   - remove BIT() macro
>   - use generic mDevicePathTemplate name
>   - put validate function under '#if !defined(MDEPKG_NDEBUG)' and
>      call from inside ASSERT_EFI_ERROR, add comment
>   - update commit message
>   - add common enum for describing controllers
>   - change authorship
> 
> - 9/12
>   - Add Leif's RB
> 
> * 10/12
>   - same modifications as 8/12
>   - use I2C flags directly and remove PCA95XX_OPERATION enum
>   - add common enum for describing controllers
> 
> * 11/12
>   - Add Leif's RB
> 
> * 12/12
>   - Add local headers
>   - Make STATIC names more generic
>   - s/GetInitializerForType/NonDiscoverableDeviceInitializerGet/
>   - Use global enum for McBin GPIO controller
> 
> 
> Marcin Wojtas (12):
>   Marvell/Library: ArmadaSoCDescLib: Add GPIO information
>   Marvell/Library: ArmadaBoardDescLib: Add GPIO information
>   Marvell/Library: Introduce MvGpioLib class
>   SolidRun/Armada80x0McBin: Extend board description library with GPIO
>   Marvell/Armada70x0Db: Extend board description library with GPIO
>   Marvell/Armada80x0Db: Extend board description library with GPIO
>   Marvell/Drivers: MvBoardDesc: Extend protocol with GPIO support
>   Marvell/Drivers: MvGpioDxe: Introduce platform GPIO driver
>   Marvell/Drivers: I2c: Use common header for macros
>   Marvell/Drivers: MvPca95xxDxe: Introduce GPIO expander driver
>   Marvell/Armada7k8k: Enable GPIO drivers compilation
>   Marvell/Armada7k8k: Introduce NonDiscoverable device init routines
> 
>  Silicon/Marvell/Marvell.dec                                                                   |   2 +
>  Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc                                                 |   3 +
>  Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc                                                |   7 +-
>  Platform/Marvell/Armada80x0Db/Armada80x0Db.dsc                                                |   3 +
>  Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.dsc                                         |   3 +
>  Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.inf           |   1 +
>  Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf               |  49 ++
>  Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.inf           |   1 +
>  Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf               |  50 ++
>  Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.inf |   1 +
>  Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf           |  50 ++
>  Silicon/Marvell/Armada7k8k/Drivers/PlatInitDxe/PlatInitDxe.inf                                |   1 +
>  Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.inf              |   1 +
>  Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.inf                                          |   1 +
>  Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf                                          |  44 ++
>  Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf                                    |  45 ++
>  Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf                                             |   1 +
>  Silicon/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf                                           |   1 +
>  Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.inf                             |   1 +
>  Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf                                           |   1 +
>  Silicon/Marvell/Library/ComPhyLib/ComPhyLib.inf                                               |   1 +
>  Silicon/Marvell/Library/IcuLib/IcuLib.inf                                                     |   1 +
>  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf                                               |  32 +
>  Silicon/Marvell/Library/UtmiPhyLib/UtmiPhyLib.inf                                             |   1 +
>  Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h                 |  23 +
>  Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h                 |  28 +
>  Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h             |  20 +
>  Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.h                |  10 +
>  Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h                                            |  49 ++
>  Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h                                      |  65 ++
>  Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.h                                         |  10 -
>  Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.h                                               |  17 +-
>  Silicon/Marvell/Include/Library/ArmadaBoardDescLib.h                                          |  23 +
>  Silicon/Marvell/Include/Library/ArmadaSoCDescLib.h                                            |  12 +
>  Silicon/Marvell/Include/Library/MvGpioLib.h                                                   |  68 +++
>  Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h                                      |  28 +
>  Silicon/Marvell/Include/Protocol/BoardDesc.h                                                  |   8 +
>  Silicon/Marvell/Include/Protocol/MvI2c.h                                                      |  31 +
>  Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c             |  24 +
>  Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c                 |  96 +++
>  Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c             |  30 +
>  Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c                 | 106 ++++
>  Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.c   |  17 +
>  Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c             |  71 +++
>  Silicon/Marvell/Applications/EepromCmd/EepromCmd.c                                            |   5 +-
>  Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.c                |  39 ++
>  Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c                                            |  50 ++
>  Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c                                            | 353 +++++++++++
>  Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c                                      | 645 ++++++++++++++++++++
>  Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.c                                         |   3 +-
>  Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.c                                               |   4 +-
>  Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.c                               |  13 +-
>  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c                                                 | 132 ++++
>  Platform/Marvell/Armada70x0Db/Armada70x0Db.fdf.inc                                            |   2 +
>  Platform/Marvell/Armada80x0Db/Armada80x0Db.fdf.inc                                            |   2 +
>  Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.fdf.inc                                     |   2 +
>  56 files changed, 2249 insertions(+), 38 deletions(-)
>  create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
>  create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
>  create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
>  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
>  create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
>  create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
>  create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h
>  create mode 100644 Silicon/Marvell/Include/Library/MvGpioLib.h
>  create mode 100644 Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h
>  create mode 100644 Silicon/Marvell/Include/Protocol/MvI2c.h
>  create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
>  create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
>  create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c
>  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c
>  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> 
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 03/12] Marvell/Library: Introduce MvGpioLib class
  2019-01-17 11:33   ` Leif Lindholm
@ 2019-01-17 12:19     ` Marcin Wojtas
  2019-01-17 14:18       ` Leif Lindholm
  0 siblings, 1 reply; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 12:19 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: edk2-devel-01, Ard Biesheuvel, nadavh, jsd@semihalf.com,
	Grzegorz Jaszczyk, Kostya Porotchkin

Hi Leif,

Sorry for omitting. I confirm the patch is:
Contributed-under: TianoCore Contribution Agreement 1.1

Will you add it (as well as remove class from the subject) or should I resubmit?

Thanks,
Marcin

czw., 17 sty 2019 o 12:33 Leif Lindholm <leif.lindholm@linaro.org> napisał(a):
>
> (Can drop the "class" from subject line)
>
> With that:
> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
>
> On Thu, Jan 17, 2019 at 12:15:06PM +0100, Marcin Wojtas wrote:
> > Following patches will add two drivers that are capable
> > of producing the generic EMBEDDED_GPIO protocol. In order
> > to handle a situation, when the consumer module attempts
> > to locate and open a proper protocol, add a library
> > helper function.
> >
> > In order to ease description of used GPIO pins and controllers
> > of the Armada 7k8k platforms, add the common enum types.
> >
> > Signed-off-by: Marcin Wojtas <mw@semihalf.com>
> > ---
> >  Silicon/Marvell/Marvell.dec                     |   1 +
> >  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf |  32 +++++
> >  Silicon/Marvell/Include/Library/MvGpioLib.h     |  68 ++++++++++
> >  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c   | 132 ++++++++++++++++++++
> >  4 files changed, 233 insertions(+)
> >  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> >  create mode 100644 Silicon/Marvell/Include/Library/MvGpioLib.h
> >  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> >
> > diff --git a/Silicon/Marvell/Marvell.dec b/Silicon/Marvell/Marvell.dec
> > index 616624e..ac922a0 100644
> > --- a/Silicon/Marvell/Marvell.dec
> > +++ b/Silicon/Marvell/Marvell.dec
> > @@ -63,6 +63,7 @@
> >    ArmadaBoardDescLib|Include/Library/ArmadaBoardDescLib.h
> >    ArmadaIcuLib|Include/Library/ArmadaIcuLib.h
> >    ArmadaSoCDescLib|Include/Library/ArmadaSoCDescLib.h
> > +  MvGpioLib|Include/Library/MvGpioLib.h
> >    SampleAtResetLib|Include/Library/SampleAtResetLib.h
> >
> >  [Protocols]
> > diff --git a/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> > new file mode 100644
> > index 0000000..3bc54ce
> > --- /dev/null
> > +++ b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> > @@ -0,0 +1,32 @@
> > +## @file
> > +#
> > +#  Copyright (C) 2018, Marvell International Ltd. and its affiliates<BR>
> > +#
> > +#  This program and the accompanying materials are licensed and made available
> > +#  under the terms and conditions of the BSD License which accompanies this
> > +#  distribution. The full text of the license may be found at
> > +#  http://opensource.org/licenses/bsd-license.php
> > +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> > +#  IMPLIED.
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x0001001A
> > +  BASE_NAME                      = MvGpioLib
> > +  FILE_GUID                      = f4386b44-6bc2-4fa1-9989-8513bbb22692
> > +  MODULE_TYPE                    = BASE
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = MvGpioLib
> > +
> > +[Sources]
> > +  MvGpioLib.c
> > +
> > +[Packages]
> > +  EmbeddedPkg/EmbeddedPkg.dec
> > +  MdePkg/MdePkg.dec
> > +  Silicon/Marvell/Marvell.dec
> > +
> > +[LibraryClasses]
> > +  DebugLib
> > diff --git a/Silicon/Marvell/Include/Library/MvGpioLib.h b/Silicon/Marvell/Include/Library/MvGpioLib.h
> > new file mode 100644
> > index 0000000..a14acdf
> > --- /dev/null
> > +++ b/Silicon/Marvell/Include/Library/MvGpioLib.h
> > @@ -0,0 +1,68 @@
> > +/**
> > +*
> > +*  Copyright (C) 2018, Marvell International Ltd. and its affiliates.
> > +*
> > +*  This program and the accompanying materials are licensed and made available
> > +*  under the terms and conditions of the BSD License which accompanies this
> > +*  distribution. The full text of the license may be found at
> > +*  http://opensource.org/licenses/bsd-license.php
> > +*
> > +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> > +*
> > +**/
> > +#ifndef __MV_GPIO_LIB_H__
> > +#define __MV_GPIO_LIB_H__
> > +
> > +#include <Protocol/EmbeddedGpio.h>
> > +
> > +typedef enum {
> > +  MV_GPIO_DRIVER_TYPE_SOC_CONTROLLER,
> > +  MV_GPIO_DRIVER_TYPE_PCA95XX,
> > +} MV_GPIO_DRIVER_TYPE;
> > +
> > +typedef enum {
> > +  MV_GPIO_AP806_CONTROLLER0,
> > +  MV_GPIO_CP0_CONTROLLER0,
> > +  MV_GPIO_CP0_CONTROLLER1,
> > +  MV_GPIO_CP1_CONTROLLER0,
> > +  MV_GPIO_CP1_CONTROLLER1,
> > +  MV_GPIO_CP2_CONTROLLER0,
> > +  MV_GPIO_CP2_CONTROLLER1,
> > +} MV_GPIO_SOC_CONTROLLER_TYPE;
> > +
> > +typedef enum {
> > +  PCA9505_ID,
> > +  PCA9534_ID,
> > +  PCA9535_ID,
> > +  PCA9536_ID,
> > +  PCA9537_ID,
> > +  PCA9538_ID,
> > +  PCA9539_ID,
> > +  PCA9554_ID,
> > +  PCA9555_ID,
> > +  PCA9556_ID,
> > +  PCA9557_ID,
> > +  PCA95XX_MAX_ID,
> > +} MV_GPIO_EXPANDER_TYPE_PCA95XX;
> > +
> > +typedef struct {
> > +  VENDOR_DEVICE_PATH        Header;
> > +  MV_GPIO_DRIVER_TYPE       GpioDriverType;
> > +  EFI_DEVICE_PATH_PROTOCOL  End;
> > +} MV_GPIO_DEVICE_PATH;
> > +
> > +typedef struct {
> > +  UINTN    ControllerId;
> > +  UINTN    PinNumber;
> > +  BOOLEAN  ActiveHigh;
> > +} MV_GPIO_PIN;
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +MvGpioGetProtocol (
> > +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> > +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> > +  );
> > +
> > +#endif // __MV_GPIO_LIB_H__
> > diff --git a/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> > new file mode 100644
> > index 0000000..a95d5ae
> > --- /dev/null
> > +++ b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> > @@ -0,0 +1,132 @@
> > +/**
> > +*
> > +*  Copyright (C) 2018, Marvell International Ltd. and its affiliates.
> > +*
> > +*  This program and the accompanying materials are licensed and made available
> > +*  under the terms and conditions of the BSD License which accompanies this
> > +*  distribution. The full text of the license may be found at
> > +*  http://opensource.org/licenses/bsd-license.php
> > +*
> > +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> > +*
> > +**/
> > +#include <Uefi.h>
> > +
> > +#include <Library/DebugLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/MvGpioLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +
> > +#include <Protocol/EmbeddedGpio.h>
> > +
> > +/*
> > + * Check if the driver type matches the requested value.
> > + * In case of the success open the GPIO protocol and return.
> > + */
> > +STATIC
> > +EFI_STATUS
> > +MvGpioFindMatchingDriver (
> > +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> > +  IN     EFI_HANDLE             HandleBuffer,
> > +  IN     EFI_DEVICE_PATH       *DevicePath,
> > +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> > +  )
> > +{
> > +  MV_GPIO_DEVICE_PATH *GpioDevicePath;
> > +  EFI_STATUS           Status;
> > +
> > +  while (!IsDevicePathEndType (DevicePath)) {
> > +    /* Check if GpioDriverType matches one found in the device path */
> > +    GpioDevicePath = (MV_GPIO_DEVICE_PATH *)DevicePath;
> > +    if (GpioDevicePath->GpioDriverType != GpioDriverType) {
> > +      DevicePath = NextDevicePathNode (DevicePath);
> > +      continue;
> > +    }
> > +
> > +    /*
> > +     * Open GpioProtocol. With EFI_OPEN_PROTOCOL_GET_PROTOCOL attribute
> > +     * the consumer is not obliged to call CloseProtocol.
> > +     */
> > +    Status = gBS->OpenProtocol (HandleBuffer,
> > +                    &gEmbeddedGpioProtocolGuid,
> > +                    (VOID **)GpioProtocol,
> > +                    gImageHandle,
> > +                    NULL,
> > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> > +    return Status;
> > +  }
> > +
> > +  return EFI_NOT_FOUND;
> > +}
> > +
> > +/*
> > + * Select desired protocol producer upon MV_GPIO_DRIVER_TYPE
> > + * field of driver's MV_GPIO_DEVICE_PATH.
> > + */
> > +EFI_STATUS
> > +EFIAPI
> > +MvGpioGetProtocol (
> > +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> > +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> > +  )
> > +{
> > +  EFI_DEVICE_PATH     *DevicePath;
> > +  EFI_HANDLE          *HandleBuffer;
> > +  EFI_STATUS           Status;
> > +  UINTN                HandleCount;
> > +  UINTN                Index;
> > +
> > +  /* Locate Handles of all EMBEDDED_GPIO producers */
> > +  Status = gBS->LocateHandleBuffer (ByProtocol,
> > +                  &gEmbeddedGpioProtocolGuid,
> > +                  NULL,
> > +                  &HandleCount,
> > +                  &HandleBuffer);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "%a: Unable to locate handles\n", __FUNCTION__));
> > +    return Status;
> > +  }
> > +
> > +  /* Iterate over all protocol producers */
> > +  for (Index = 0; Index < HandleCount; Index++) {
> > +    /* Open device path protocol installed on each handle */
> > +    Status = gBS->OpenProtocol (HandleBuffer[Index],
> > +                    &gEfiDevicePathProtocolGuid,
> > +                    (VOID **)&DevicePath,
> > +                    gImageHandle,
> > +                    NULL,
> > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_ERROR, "%a: Unable to find DevicePath\n", __FUNCTION__));
> > +      continue;
> > +    }
> > +
> > +    /*
> > +     * Check if the driver type matches the requested value.
> > +     * In case of the success open the GPIO protocol and return.
> > +     * If there is no match, repeat procedure with the next handle.
> > +     */
> > +    Status = MvGpioFindMatchingDriver (GpioDriverType,
> > +               HandleBuffer[Index],
> > +               DevicePath,
> > +               GpioProtocol);
> > +    if (Status == EFI_NOT_FOUND) {
> > +      continue;
> > +    } else if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_ERROR,
> > +        "%a: Unable to open GPIO protocol\n",
> > +        __FUNCTION__));
> > +    }
> > +
> > +    gBS->FreePool (HandleBuffer);
> > +
> > +    return Status;
> > +  }
> > +
> > +  /* No matching GPIO protocol producer was found */
> > +  gBS->FreePool (HandleBuffer);
> > +
> > +  return EFI_NOT_FOUND;
> > +}
> > --
> > 2.7.4
> >


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 00/12] Armada 7k8k GPIO support
  2019-01-17 12:03 ` [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Leif Lindholm
@ 2019-01-17 12:26   ` Marcin Wojtas
  0 siblings, 0 replies; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 12:26 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: edk2-devel-01, Ard Biesheuvel, nadavh, jsd@semihalf.com,
	Grzegorz Jaszczyk, Kostya Porotchkin

Hi Leif,

czw., 17 sty 2019 o 13:04 Leif Lindholm <leif.lindholm@linaro.org> napisał(a):
>
> So, I was about to say that apart from the "class" to be deleted from
> 3/12 subject line, things were fine so I was going to fix that locally
> and push.
>
> However. 3/12 is missing the Contributed-under tag.
> Can you please separately confirm that it is intended to be
> contributed under TianoCore Contribution Agreement 1.1?
>

Sure, done. Please let know if I should resubmit.

Best regards,
Marcin

> /                                                                                                                 Leif
>
> On Thu, Jan 17, 2019 at 12:15:03PM +0100, Marcin Wojtas wrote:
> > Hi,
> >
> > I submit v3 of the GPIO patchset for the Marvell SoCs.
> > The changes are not significant and they address all the comments
> > from the previous version. Please find the details in the changelog
> > below.
> >
> > Patches are available in the github:
> > https://github.com/MarvellEmbeddedProcessors/edk2-open-platform/commits/gpio-upstream-r20190117
> >
> > I am looking forward to your feedback.
> >
> > Best regards,
> > Marcin
> >
> > Changelog:
> > v2->v3:
> > * 1,2,4,12/12
> >    - Add Leif's RB
> >
> > * 3/12
> >   - Change MvGpio.h to be library header (Library/MvGpioLib.h)
> >   - Introduce MvGpioLib library
> >   - Add PCA_ID enums in this patch (instead from PCA9xxx addition)
> >
> > * 5,6/12
> >   - Use PCA_ID enum from the beginning
> >
> > * 7/12
> >   - Use static global variable and allocate it only only once
> >   - s/I2C/GPIO/
> >
> > * 8/12
> >   - Simplify error path after changing approach to not freeing
> >     already allocated GpioDescription in MvBoardDescDxe
> >   - Change signature to non-generic
> >
> > * 10/12
> >   - Simplify error path after changing approach to not freeing
> >     already allocated GpioDescription in MvBoardDescDxe
> >   - No need to update PCA_ID in this patch
> >
> > v1->v2:
> > * All
> >   - rebase on top of the master branch and Xenon changes
> >
> > * 1/12
> >   - s/AP/AP806/ in order to avoid confusion
> >   - drop desc/DESC usage and improve variables naming
> >   - use GPIO_CONTROLLER from EmbeddedGpio.h instead of custom MV_SOC_GPIO
> >   - update commit message
> >
> > * 2,3,4,5/12
> >   - drop desc/DESC usage and improve variables naming
> >   - drop reference to I2c and use GpioExpander
> >   - improve commit logs
> >
> > * 6/12
> >   - drop desc/DESC usage and improve variables naming
> >   - drop reference to I2c and use GpioExpander
> >   - remove global variable - same as for other interfaces the consumer
> >     is responsible for avoiding memory leak
> >
> > * 7/12
> >   - use MV_GPIO_ prefix
> >   - switch to EMBEDDED_GPIO
> >   - remove custom Marvell GPIO Protocol and types
> >   - add subroutine to MvGpioGetProtocol and more coments to clarify the code
> >   - add driver types and related enums in other commits
> >
> > * 8/12
> >   - extend error path in the entry point, rename variables
> >   - use MV_GPIO_ prefix
> >   - switch to EMBEDDED_GPIO
> >   - remove custom Marvell GPIO Protocol and types
> >   - replace '!!' expression for obtaining pin state
> >   - remove BIT() macro
> >   - use generic mDevicePathTemplate name
> >   - put validate function under '#if !defined(MDEPKG_NDEBUG)' and
> >      call from inside ASSERT_EFI_ERROR, add comment
> >   - update commit message
> >   - add common enum for describing controllers
> >   - change authorship
> >
> > - 9/12
> >   - Add Leif's RB
> >
> > * 10/12
> >   - same modifications as 8/12
> >   - use I2C flags directly and remove PCA95XX_OPERATION enum
> >   - add common enum for describing controllers
> >
> > * 11/12
> >   - Add Leif's RB
> >
> > * 12/12
> >   - Add local headers
> >   - Make STATIC names more generic
> >   - s/GetInitializerForType/NonDiscoverableDeviceInitializerGet/
> >   - Use global enum for McBin GPIO controller
> >
> >
> > Marcin Wojtas (12):
> >   Marvell/Library: ArmadaSoCDescLib: Add GPIO information
> >   Marvell/Library: ArmadaBoardDescLib: Add GPIO information
> >   Marvell/Library: Introduce MvGpioLib class
> >   SolidRun/Armada80x0McBin: Extend board description library with GPIO
> >   Marvell/Armada70x0Db: Extend board description library with GPIO
> >   Marvell/Armada80x0Db: Extend board description library with GPIO
> >   Marvell/Drivers: MvBoardDesc: Extend protocol with GPIO support
> >   Marvell/Drivers: MvGpioDxe: Introduce platform GPIO driver
> >   Marvell/Drivers: I2c: Use common header for macros
> >   Marvell/Drivers: MvPca95xxDxe: Introduce GPIO expander driver
> >   Marvell/Armada7k8k: Enable GPIO drivers compilation
> >   Marvell/Armada7k8k: Introduce NonDiscoverable device init routines
> >
> >  Silicon/Marvell/Marvell.dec                                                                   |   2 +
> >  Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc                                                 |   3 +
> >  Platform/Marvell/Armada70x0Db/Armada70x0Db.dsc                                                |   7 +-
> >  Platform/Marvell/Armada80x0Db/Armada80x0Db.dsc                                                |   3 +
> >  Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.dsc                                         |   3 +
> >  Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.inf           |   1 +
> >  Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf               |  49 ++
> >  Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.inf           |   1 +
> >  Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf               |  50 ++
> >  Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.inf |   1 +
> >  Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf           |  50 ++
> >  Silicon/Marvell/Armada7k8k/Drivers/PlatInitDxe/PlatInitDxe.inf                                |   1 +
> >  Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.inf              |   1 +
> >  Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.inf                                          |   1 +
> >  Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf                                          |  44 ++
> >  Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf                                    |  45 ++
> >  Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf                                             |   1 +
> >  Silicon/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf                                           |   1 +
> >  Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.inf                             |   1 +
> >  Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf                                           |   1 +
> >  Silicon/Marvell/Library/ComPhyLib/ComPhyLib.inf                                               |   1 +
> >  Silicon/Marvell/Library/IcuLib/IcuLib.inf                                                     |   1 +
> >  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf                                               |  32 +
> >  Silicon/Marvell/Library/UtmiPhyLib/UtmiPhyLib.inf                                             |   1 +
> >  Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h                 |  23 +
> >  Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h                 |  28 +
> >  Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h             |  20 +
> >  Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.h                |  10 +
> >  Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h                                            |  49 ++
> >  Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h                                      |  65 ++
> >  Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.h                                         |  10 -
> >  Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.h                                               |  17 +-
> >  Silicon/Marvell/Include/Library/ArmadaBoardDescLib.h                                          |  23 +
> >  Silicon/Marvell/Include/Library/ArmadaSoCDescLib.h                                            |  12 +
> >  Silicon/Marvell/Include/Library/MvGpioLib.h                                                   |  68 +++
> >  Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h                                      |  28 +
> >  Silicon/Marvell/Include/Protocol/BoardDesc.h                                                  |   8 +
> >  Silicon/Marvell/Include/Protocol/MvI2c.h                                                      |  31 +
> >  Platform/Marvell/Armada70x0Db/Armada70x0DbBoardDescLib/Armada70x0DbBoardDescLib.c             |  24 +
> >  Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c                 |  96 +++
> >  Platform/Marvell/Armada80x0Db/Armada80x0DbBoardDescLib/Armada80x0DbBoardDescLib.c             |  30 +
> >  Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c                 | 106 ++++
> >  Platform/SolidRun/Armada80x0McBin/Armada80x0McBinBoardDescLib/Armada80x0McBinBoardDescLib.c   |  17 +
> >  Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c             |  71 +++
> >  Silicon/Marvell/Applications/EepromCmd/EepromCmd.c                                            |   5 +-
> >  Silicon/Marvell/Armada7k8k/Library/Armada7k8kSoCDescLib/Armada7k8kSoCDescLib.c                |  39 ++
> >  Silicon/Marvell/Drivers/BoardDesc/MvBoardDescDxe.c                                            |  50 ++
> >  Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c                                            | 353 +++++++++++
> >  Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c                                      | 645 ++++++++++++++++++++
> >  Silicon/Marvell/Drivers/I2c/MvEepromDxe/MvEepromDxe.c                                         |   3 +-
> >  Silicon/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.c                                               |   4 +-
> >  Silicon/Marvell/Drivers/NonDiscoverableDxe/NonDiscoverableDxe.c                               |  13 +-
> >  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c                                                 | 132 ++++
> >  Platform/Marvell/Armada70x0Db/Armada70x0Db.fdf.inc                                            |   2 +
> >  Platform/Marvell/Armada80x0Db/Armada80x0Db.fdf.inc                                            |   2 +
> >  Platform/SolidRun/Armada80x0McBin/Armada80x0McBin.fdf.inc                                     |   2 +
> >  56 files changed, 2249 insertions(+), 38 deletions(-)
> >  create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
> >  create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
> >  create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.inf
> >  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf
> >  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.inf
> >  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> >  create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
> >  create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.h
> >  create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.h
> >  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h
> >  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.h
> >  create mode 100644 Silicon/Marvell/Include/Library/MvGpioLib.h
> >  create mode 100644 Silicon/Marvell/Include/Library/NonDiscoverableInitLib.h
> >  create mode 100644 Silicon/Marvell/Include/Protocol/MvI2c.h
> >  create mode 100644 Platform/Marvell/Armada70x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
> >  create mode 100644 Platform/Marvell/Armada80x0Db/NonDiscoverableInitLib/NonDiscoverableInitLib.c
> >  create mode 100644 Platform/SolidRun/Armada80x0McBin/NonDiscoverableInitLib/NonDiscoverableInitLib.c
> >  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c
> >  create mode 100644 Silicon/Marvell/Drivers/Gpio/MvPca95xxDxe/MvPca95xxDxe.c
> >  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> >
> > --
> > 2.7.4
> >


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 03/12] Marvell/Library: Introduce MvGpioLib class
  2019-01-17 12:19     ` Marcin Wojtas
@ 2019-01-17 14:18       ` Leif Lindholm
  2019-01-17 14:39         ` Marcin Wojtas
  0 siblings, 1 reply; 24+ messages in thread
From: Leif Lindholm @ 2019-01-17 14:18 UTC (permalink / raw)
  To: Marcin Wojtas
  Cc: edk2-devel-01, Ard Biesheuvel, nadavh, jsd@semihalf.com,
	Grzegorz Jaszczyk, Kostya Porotchkin

Series pushed as 944fbb62d6..9b725b6ebb

Thanks!

On Thu, Jan 17, 2019 at 01:19:52PM +0100, Marcin Wojtas wrote:
> Hi Leif,
> 
> Sorry for omitting. I confirm the patch is:
> Contributed-under: TianoCore Contribution Agreement 1.1
> 
> Will you add it (as well as remove class from the subject) or should I resubmit?
> 
> Thanks,
> Marcin
> 
> czw., 17 sty 2019 o 12:33 Leif Lindholm <leif.lindholm@linaro.org> napisał(a):
> >
> > (Can drop the "class" from subject line)
> >
> > With that:
> > Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
> >
> > On Thu, Jan 17, 2019 at 12:15:06PM +0100, Marcin Wojtas wrote:
> > > Following patches will add two drivers that are capable
> > > of producing the generic EMBEDDED_GPIO protocol. In order
> > > to handle a situation, when the consumer module attempts
> > > to locate and open a proper protocol, add a library
> > > helper function.
> > >
> > > In order to ease description of used GPIO pins and controllers
> > > of the Armada 7k8k platforms, add the common enum types.
> > >
> > > Signed-off-by: Marcin Wojtas <mw@semihalf.com>
> > > ---
> > >  Silicon/Marvell/Marvell.dec                     |   1 +
> > >  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf |  32 +++++
> > >  Silicon/Marvell/Include/Library/MvGpioLib.h     |  68 ++++++++++
> > >  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c   | 132 ++++++++++++++++++++
> > >  4 files changed, 233 insertions(+)
> > >  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> > >  create mode 100644 Silicon/Marvell/Include/Library/MvGpioLib.h
> > >  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> > >
> > > diff --git a/Silicon/Marvell/Marvell.dec b/Silicon/Marvell/Marvell.dec
> > > index 616624e..ac922a0 100644
> > > --- a/Silicon/Marvell/Marvell.dec
> > > +++ b/Silicon/Marvell/Marvell.dec
> > > @@ -63,6 +63,7 @@
> > >    ArmadaBoardDescLib|Include/Library/ArmadaBoardDescLib.h
> > >    ArmadaIcuLib|Include/Library/ArmadaIcuLib.h
> > >    ArmadaSoCDescLib|Include/Library/ArmadaSoCDescLib.h
> > > +  MvGpioLib|Include/Library/MvGpioLib.h
> > >    SampleAtResetLib|Include/Library/SampleAtResetLib.h
> > >
> > >  [Protocols]
> > > diff --git a/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> > > new file mode 100644
> > > index 0000000..3bc54ce
> > > --- /dev/null
> > > +++ b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> > > @@ -0,0 +1,32 @@
> > > +## @file
> > > +#
> > > +#  Copyright (C) 2018, Marvell International Ltd. and its affiliates<BR>
> > > +#
> > > +#  This program and the accompanying materials are licensed and made available
> > > +#  under the terms and conditions of the BSD License which accompanies this
> > > +#  distribution. The full text of the license may be found at
> > > +#  http://opensource.org/licenses/bsd-license.php
> > > +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > > +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> > > +#  IMPLIED.
> > > +#
> > > +##
> > > +
> > > +[Defines]
> > > +  INF_VERSION                    = 0x0001001A
> > > +  BASE_NAME                      = MvGpioLib
> > > +  FILE_GUID                      = f4386b44-6bc2-4fa1-9989-8513bbb22692
> > > +  MODULE_TYPE                    = BASE
> > > +  VERSION_STRING                 = 1.0
> > > +  LIBRARY_CLASS                  = MvGpioLib
> > > +
> > > +[Sources]
> > > +  MvGpioLib.c
> > > +
> > > +[Packages]
> > > +  EmbeddedPkg/EmbeddedPkg.dec
> > > +  MdePkg/MdePkg.dec
> > > +  Silicon/Marvell/Marvell.dec
> > > +
> > > +[LibraryClasses]
> > > +  DebugLib
> > > diff --git a/Silicon/Marvell/Include/Library/MvGpioLib.h b/Silicon/Marvell/Include/Library/MvGpioLib.h
> > > new file mode 100644
> > > index 0000000..a14acdf
> > > --- /dev/null
> > > +++ b/Silicon/Marvell/Include/Library/MvGpioLib.h
> > > @@ -0,0 +1,68 @@
> > > +/**
> > > +*
> > > +*  Copyright (C) 2018, Marvell International Ltd. and its affiliates.
> > > +*
> > > +*  This program and the accompanying materials are licensed and made available
> > > +*  under the terms and conditions of the BSD License which accompanies this
> > > +*  distribution. The full text of the license may be found at
> > > +*  http://opensource.org/licenses/bsd-license.php
> > > +*
> > > +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > > +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> > > +*
> > > +**/
> > > +#ifndef __MV_GPIO_LIB_H__
> > > +#define __MV_GPIO_LIB_H__
> > > +
> > > +#include <Protocol/EmbeddedGpio.h>
> > > +
> > > +typedef enum {
> > > +  MV_GPIO_DRIVER_TYPE_SOC_CONTROLLER,
> > > +  MV_GPIO_DRIVER_TYPE_PCA95XX,
> > > +} MV_GPIO_DRIVER_TYPE;
> > > +
> > > +typedef enum {
> > > +  MV_GPIO_AP806_CONTROLLER0,
> > > +  MV_GPIO_CP0_CONTROLLER0,
> > > +  MV_GPIO_CP0_CONTROLLER1,
> > > +  MV_GPIO_CP1_CONTROLLER0,
> > > +  MV_GPIO_CP1_CONTROLLER1,
> > > +  MV_GPIO_CP2_CONTROLLER0,
> > > +  MV_GPIO_CP2_CONTROLLER1,
> > > +} MV_GPIO_SOC_CONTROLLER_TYPE;
> > > +
> > > +typedef enum {
> > > +  PCA9505_ID,
> > > +  PCA9534_ID,
> > > +  PCA9535_ID,
> > > +  PCA9536_ID,
> > > +  PCA9537_ID,
> > > +  PCA9538_ID,
> > > +  PCA9539_ID,
> > > +  PCA9554_ID,
> > > +  PCA9555_ID,
> > > +  PCA9556_ID,
> > > +  PCA9557_ID,
> > > +  PCA95XX_MAX_ID,
> > > +} MV_GPIO_EXPANDER_TYPE_PCA95XX;
> > > +
> > > +typedef struct {
> > > +  VENDOR_DEVICE_PATH        Header;
> > > +  MV_GPIO_DRIVER_TYPE       GpioDriverType;
> > > +  EFI_DEVICE_PATH_PROTOCOL  End;
> > > +} MV_GPIO_DEVICE_PATH;
> > > +
> > > +typedef struct {
> > > +  UINTN    ControllerId;
> > > +  UINTN    PinNumber;
> > > +  BOOLEAN  ActiveHigh;
> > > +} MV_GPIO_PIN;
> > > +
> > > +EFI_STATUS
> > > +EFIAPI
> > > +MvGpioGetProtocol (
> > > +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> > > +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> > > +  );
> > > +
> > > +#endif // __MV_GPIO_LIB_H__
> > > diff --git a/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> > > new file mode 100644
> > > index 0000000..a95d5ae
> > > --- /dev/null
> > > +++ b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> > > @@ -0,0 +1,132 @@
> > > +/**
> > > +*
> > > +*  Copyright (C) 2018, Marvell International Ltd. and its affiliates.
> > > +*
> > > +*  This program and the accompanying materials are licensed and made available
> > > +*  under the terms and conditions of the BSD License which accompanies this
> > > +*  distribution. The full text of the license may be found at
> > > +*  http://opensource.org/licenses/bsd-license.php
> > > +*
> > > +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > > +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> > > +*
> > > +**/
> > > +#include <Uefi.h>
> > > +
> > > +#include <Library/DebugLib.h>
> > > +#include <Library/DevicePathLib.h>
> > > +#include <Library/MemoryAllocationLib.h>
> > > +#include <Library/MvGpioLib.h>
> > > +#include <Library/UefiBootServicesTableLib.h>
> > > +
> > > +#include <Protocol/EmbeddedGpio.h>
> > > +
> > > +/*
> > > + * Check if the driver type matches the requested value.
> > > + * In case of the success open the GPIO protocol and return.
> > > + */
> > > +STATIC
> > > +EFI_STATUS
> > > +MvGpioFindMatchingDriver (
> > > +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> > > +  IN     EFI_HANDLE             HandleBuffer,
> > > +  IN     EFI_DEVICE_PATH       *DevicePath,
> > > +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> > > +  )
> > > +{
> > > +  MV_GPIO_DEVICE_PATH *GpioDevicePath;
> > > +  EFI_STATUS           Status;
> > > +
> > > +  while (!IsDevicePathEndType (DevicePath)) {
> > > +    /* Check if GpioDriverType matches one found in the device path */
> > > +    GpioDevicePath = (MV_GPIO_DEVICE_PATH *)DevicePath;
> > > +    if (GpioDevicePath->GpioDriverType != GpioDriverType) {
> > > +      DevicePath = NextDevicePathNode (DevicePath);
> > > +      continue;
> > > +    }
> > > +
> > > +    /*
> > > +     * Open GpioProtocol. With EFI_OPEN_PROTOCOL_GET_PROTOCOL attribute
> > > +     * the consumer is not obliged to call CloseProtocol.
> > > +     */
> > > +    Status = gBS->OpenProtocol (HandleBuffer,
> > > +                    &gEmbeddedGpioProtocolGuid,
> > > +                    (VOID **)GpioProtocol,
> > > +                    gImageHandle,
> > > +                    NULL,
> > > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> > > +    return Status;
> > > +  }
> > > +
> > > +  return EFI_NOT_FOUND;
> > > +}
> > > +
> > > +/*
> > > + * Select desired protocol producer upon MV_GPIO_DRIVER_TYPE
> > > + * field of driver's MV_GPIO_DEVICE_PATH.
> > > + */
> > > +EFI_STATUS
> > > +EFIAPI
> > > +MvGpioGetProtocol (
> > > +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> > > +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> > > +  )
> > > +{
> > > +  EFI_DEVICE_PATH     *DevicePath;
> > > +  EFI_HANDLE          *HandleBuffer;
> > > +  EFI_STATUS           Status;
> > > +  UINTN                HandleCount;
> > > +  UINTN                Index;
> > > +
> > > +  /* Locate Handles of all EMBEDDED_GPIO producers */
> > > +  Status = gBS->LocateHandleBuffer (ByProtocol,
> > > +                  &gEmbeddedGpioProtocolGuid,
> > > +                  NULL,
> > > +                  &HandleCount,
> > > +                  &HandleBuffer);
> > > +  if (EFI_ERROR (Status)) {
> > > +    DEBUG ((DEBUG_ERROR, "%a: Unable to locate handles\n", __FUNCTION__));
> > > +    return Status;
> > > +  }
> > > +
> > > +  /* Iterate over all protocol producers */
> > > +  for (Index = 0; Index < HandleCount; Index++) {
> > > +    /* Open device path protocol installed on each handle */
> > > +    Status = gBS->OpenProtocol (HandleBuffer[Index],
> > > +                    &gEfiDevicePathProtocolGuid,
> > > +                    (VOID **)&DevicePath,
> > > +                    gImageHandle,
> > > +                    NULL,
> > > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> > > +    if (EFI_ERROR (Status)) {
> > > +      DEBUG ((DEBUG_ERROR, "%a: Unable to find DevicePath\n", __FUNCTION__));
> > > +      continue;
> > > +    }
> > > +
> > > +    /*
> > > +     * Check if the driver type matches the requested value.
> > > +     * In case of the success open the GPIO protocol and return.
> > > +     * If there is no match, repeat procedure with the next handle.
> > > +     */
> > > +    Status = MvGpioFindMatchingDriver (GpioDriverType,
> > > +               HandleBuffer[Index],
> > > +               DevicePath,
> > > +               GpioProtocol);
> > > +    if (Status == EFI_NOT_FOUND) {
> > > +      continue;
> > > +    } else if (EFI_ERROR (Status)) {
> > > +      DEBUG ((DEBUG_ERROR,
> > > +        "%a: Unable to open GPIO protocol\n",
> > > +        __FUNCTION__));
> > > +    }
> > > +
> > > +    gBS->FreePool (HandleBuffer);
> > > +
> > > +    return Status;
> > > +  }
> > > +
> > > +  /* No matching GPIO protocol producer was found */
> > > +  gBS->FreePool (HandleBuffer);
> > > +
> > > +  return EFI_NOT_FOUND;
> > > +}
> > > --
> > > 2.7.4
> > >


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [platforms: PATCH v3 03/12] Marvell/Library: Introduce MvGpioLib class
  2019-01-17 14:18       ` Leif Lindholm
@ 2019-01-17 14:39         ` Marcin Wojtas
  0 siblings, 0 replies; 24+ messages in thread
From: Marcin Wojtas @ 2019-01-17 14:39 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: edk2-devel-01, Ard Biesheuvel, nadavh, jsd@semihalf.com,
	Grzegorz Jaszczyk, Kostya Porotchkin

Thanks a lot!

Best regards,
Marcin

czw., 17 sty 2019 o 15:18 Leif Lindholm <leif.lindholm@linaro.org> napisał(a):
>
> Series pushed as 944fbb62d6..9b725b6ebb
>
> Thanks!
>
> On Thu, Jan 17, 2019 at 01:19:52PM +0100, Marcin Wojtas wrote:
> > Hi Leif,
> >
> > Sorry for omitting. I confirm the patch is:
> > Contributed-under: TianoCore Contribution Agreement 1.1
> >
> > Will you add it (as well as remove class from the subject) or should I resubmit?
> >
> > Thanks,
> > Marcin
> >
> > czw., 17 sty 2019 o 12:33 Leif Lindholm <leif.lindholm@linaro.org> napisał(a):
> > >
> > > (Can drop the "class" from subject line)
> > >
> > > With that:
> > > Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
> > >
> > > On Thu, Jan 17, 2019 at 12:15:06PM +0100, Marcin Wojtas wrote:
> > > > Following patches will add two drivers that are capable
> > > > of producing the generic EMBEDDED_GPIO protocol. In order
> > > > to handle a situation, when the consumer module attempts
> > > > to locate and open a proper protocol, add a library
> > > > helper function.
> > > >
> > > > In order to ease description of used GPIO pins and controllers
> > > > of the Armada 7k8k platforms, add the common enum types.
> > > >
> > > > Signed-off-by: Marcin Wojtas <mw@semihalf.com>
> > > > ---
> > > >  Silicon/Marvell/Marvell.dec                     |   1 +
> > > >  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf |  32 +++++
> > > >  Silicon/Marvell/Include/Library/MvGpioLib.h     |  68 ++++++++++
> > > >  Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c   | 132 ++++++++++++++++++++
> > > >  4 files changed, 233 insertions(+)
> > > >  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> > > >  create mode 100644 Silicon/Marvell/Include/Library/MvGpioLib.h
> > > >  create mode 100644 Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> > > >
> > > > diff --git a/Silicon/Marvell/Marvell.dec b/Silicon/Marvell/Marvell.dec
> > > > index 616624e..ac922a0 100644
> > > > --- a/Silicon/Marvell/Marvell.dec
> > > > +++ b/Silicon/Marvell/Marvell.dec
> > > > @@ -63,6 +63,7 @@
> > > >    ArmadaBoardDescLib|Include/Library/ArmadaBoardDescLib.h
> > > >    ArmadaIcuLib|Include/Library/ArmadaIcuLib.h
> > > >    ArmadaSoCDescLib|Include/Library/ArmadaSoCDescLib.h
> > > > +  MvGpioLib|Include/Library/MvGpioLib.h
> > > >    SampleAtResetLib|Include/Library/SampleAtResetLib.h
> > > >
> > > >  [Protocols]
> > > > diff --git a/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> > > > new file mode 100644
> > > > index 0000000..3bc54ce
> > > > --- /dev/null
> > > > +++ b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.inf
> > > > @@ -0,0 +1,32 @@
> > > > +## @file
> > > > +#
> > > > +#  Copyright (C) 2018, Marvell International Ltd. and its affiliates<BR>
> > > > +#
> > > > +#  This program and the accompanying materials are licensed and made available
> > > > +#  under the terms and conditions of the BSD License which accompanies this
> > > > +#  distribution. The full text of the license may be found at
> > > > +#  http://opensource.org/licenses/bsd-license.php
> > > > +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > > > +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> > > > +#  IMPLIED.
> > > > +#
> > > > +##
> > > > +
> > > > +[Defines]
> > > > +  INF_VERSION                    = 0x0001001A
> > > > +  BASE_NAME                      = MvGpioLib
> > > > +  FILE_GUID                      = f4386b44-6bc2-4fa1-9989-8513bbb22692
> > > > +  MODULE_TYPE                    = BASE
> > > > +  VERSION_STRING                 = 1.0
> > > > +  LIBRARY_CLASS                  = MvGpioLib
> > > > +
> > > > +[Sources]
> > > > +  MvGpioLib.c
> > > > +
> > > > +[Packages]
> > > > +  EmbeddedPkg/EmbeddedPkg.dec
> > > > +  MdePkg/MdePkg.dec
> > > > +  Silicon/Marvell/Marvell.dec
> > > > +
> > > > +[LibraryClasses]
> > > > +  DebugLib
> > > > diff --git a/Silicon/Marvell/Include/Library/MvGpioLib.h b/Silicon/Marvell/Include/Library/MvGpioLib.h
> > > > new file mode 100644
> > > > index 0000000..a14acdf
> > > > --- /dev/null
> > > > +++ b/Silicon/Marvell/Include/Library/MvGpioLib.h
> > > > @@ -0,0 +1,68 @@
> > > > +/**
> > > > +*
> > > > +*  Copyright (C) 2018, Marvell International Ltd. and its affiliates.
> > > > +*
> > > > +*  This program and the accompanying materials are licensed and made available
> > > > +*  under the terms and conditions of the BSD License which accompanies this
> > > > +*  distribution. The full text of the license may be found at
> > > > +*  http://opensource.org/licenses/bsd-license.php
> > > > +*
> > > > +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > > > +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> > > > +*
> > > > +**/
> > > > +#ifndef __MV_GPIO_LIB_H__
> > > > +#define __MV_GPIO_LIB_H__
> > > > +
> > > > +#include <Protocol/EmbeddedGpio.h>
> > > > +
> > > > +typedef enum {
> > > > +  MV_GPIO_DRIVER_TYPE_SOC_CONTROLLER,
> > > > +  MV_GPIO_DRIVER_TYPE_PCA95XX,
> > > > +} MV_GPIO_DRIVER_TYPE;
> > > > +
> > > > +typedef enum {
> > > > +  MV_GPIO_AP806_CONTROLLER0,
> > > > +  MV_GPIO_CP0_CONTROLLER0,
> > > > +  MV_GPIO_CP0_CONTROLLER1,
> > > > +  MV_GPIO_CP1_CONTROLLER0,
> > > > +  MV_GPIO_CP1_CONTROLLER1,
> > > > +  MV_GPIO_CP2_CONTROLLER0,
> > > > +  MV_GPIO_CP2_CONTROLLER1,
> > > > +} MV_GPIO_SOC_CONTROLLER_TYPE;
> > > > +
> > > > +typedef enum {
> > > > +  PCA9505_ID,
> > > > +  PCA9534_ID,
> > > > +  PCA9535_ID,
> > > > +  PCA9536_ID,
> > > > +  PCA9537_ID,
> > > > +  PCA9538_ID,
> > > > +  PCA9539_ID,
> > > > +  PCA9554_ID,
> > > > +  PCA9555_ID,
> > > > +  PCA9556_ID,
> > > > +  PCA9557_ID,
> > > > +  PCA95XX_MAX_ID,
> > > > +} MV_GPIO_EXPANDER_TYPE_PCA95XX;
> > > > +
> > > > +typedef struct {
> > > > +  VENDOR_DEVICE_PATH        Header;
> > > > +  MV_GPIO_DRIVER_TYPE       GpioDriverType;
> > > > +  EFI_DEVICE_PATH_PROTOCOL  End;
> > > > +} MV_GPIO_DEVICE_PATH;
> > > > +
> > > > +typedef struct {
> > > > +  UINTN    ControllerId;
> > > > +  UINTN    PinNumber;
> > > > +  BOOLEAN  ActiveHigh;
> > > > +} MV_GPIO_PIN;
> > > > +
> > > > +EFI_STATUS
> > > > +EFIAPI
> > > > +MvGpioGetProtocol (
> > > > +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> > > > +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> > > > +  );
> > > > +
> > > > +#endif // __MV_GPIO_LIB_H__
> > > > diff --git a/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> > > > new file mode 100644
> > > > index 0000000..a95d5ae
> > > > --- /dev/null
> > > > +++ b/Silicon/Marvell/Library/MvGpioLib/MvGpioLib.c
> > > > @@ -0,0 +1,132 @@
> > > > +/**
> > > > +*
> > > > +*  Copyright (C) 2018, Marvell International Ltd. and its affiliates.
> > > > +*
> > > > +*  This program and the accompanying materials are licensed and made available
> > > > +*  under the terms and conditions of the BSD License which accompanies this
> > > > +*  distribution. The full text of the license may be found at
> > > > +*  http://opensource.org/licenses/bsd-license.php
> > > > +*
> > > > +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > > > +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> > > > +*
> > > > +**/
> > > > +#include <Uefi.h>
> > > > +
> > > > +#include <Library/DebugLib.h>
> > > > +#include <Library/DevicePathLib.h>
> > > > +#include <Library/MemoryAllocationLib.h>
> > > > +#include <Library/MvGpioLib.h>
> > > > +#include <Library/UefiBootServicesTableLib.h>
> > > > +
> > > > +#include <Protocol/EmbeddedGpio.h>
> > > > +
> > > > +/*
> > > > + * Check if the driver type matches the requested value.
> > > > + * In case of the success open the GPIO protocol and return.
> > > > + */
> > > > +STATIC
> > > > +EFI_STATUS
> > > > +MvGpioFindMatchingDriver (
> > > > +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> > > > +  IN     EFI_HANDLE             HandleBuffer,
> > > > +  IN     EFI_DEVICE_PATH       *DevicePath,
> > > > +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> > > > +  )
> > > > +{
> > > > +  MV_GPIO_DEVICE_PATH *GpioDevicePath;
> > > > +  EFI_STATUS           Status;
> > > > +
> > > > +  while (!IsDevicePathEndType (DevicePath)) {
> > > > +    /* Check if GpioDriverType matches one found in the device path */
> > > > +    GpioDevicePath = (MV_GPIO_DEVICE_PATH *)DevicePath;
> > > > +    if (GpioDevicePath->GpioDriverType != GpioDriverType) {
> > > > +      DevicePath = NextDevicePathNode (DevicePath);
> > > > +      continue;
> > > > +    }
> > > > +
> > > > +    /*
> > > > +     * Open GpioProtocol. With EFI_OPEN_PROTOCOL_GET_PROTOCOL attribute
> > > > +     * the consumer is not obliged to call CloseProtocol.
> > > > +     */
> > > > +    Status = gBS->OpenProtocol (HandleBuffer,
> > > > +                    &gEmbeddedGpioProtocolGuid,
> > > > +                    (VOID **)GpioProtocol,
> > > > +                    gImageHandle,
> > > > +                    NULL,
> > > > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> > > > +    return Status;
> > > > +  }
> > > > +
> > > > +  return EFI_NOT_FOUND;
> > > > +}
> > > > +
> > > > +/*
> > > > + * Select desired protocol producer upon MV_GPIO_DRIVER_TYPE
> > > > + * field of driver's MV_GPIO_DEVICE_PATH.
> > > > + */
> > > > +EFI_STATUS
> > > > +EFIAPI
> > > > +MvGpioGetProtocol (
> > > > +  IN     MV_GPIO_DRIVER_TYPE    GpioDriverType,
> > > > +  IN OUT EMBEDDED_GPIO        **GpioProtocol
> > > > +  )
> > > > +{
> > > > +  EFI_DEVICE_PATH     *DevicePath;
> > > > +  EFI_HANDLE          *HandleBuffer;
> > > > +  EFI_STATUS           Status;
> > > > +  UINTN                HandleCount;
> > > > +  UINTN                Index;
> > > > +
> > > > +  /* Locate Handles of all EMBEDDED_GPIO producers */
> > > > +  Status = gBS->LocateHandleBuffer (ByProtocol,
> > > > +                  &gEmbeddedGpioProtocolGuid,
> > > > +                  NULL,
> > > > +                  &HandleCount,
> > > > +                  &HandleBuffer);
> > > > +  if (EFI_ERROR (Status)) {
> > > > +    DEBUG ((DEBUG_ERROR, "%a: Unable to locate handles\n", __FUNCTION__));
> > > > +    return Status;
> > > > +  }
> > > > +
> > > > +  /* Iterate over all protocol producers */
> > > > +  for (Index = 0; Index < HandleCount; Index++) {
> > > > +    /* Open device path protocol installed on each handle */
> > > > +    Status = gBS->OpenProtocol (HandleBuffer[Index],
> > > > +                    &gEfiDevicePathProtocolGuid,
> > > > +                    (VOID **)&DevicePath,
> > > > +                    gImageHandle,
> > > > +                    NULL,
> > > > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> > > > +    if (EFI_ERROR (Status)) {
> > > > +      DEBUG ((DEBUG_ERROR, "%a: Unable to find DevicePath\n", __FUNCTION__));
> > > > +      continue;
> > > > +    }
> > > > +
> > > > +    /*
> > > > +     * Check if the driver type matches the requested value.
> > > > +     * In case of the success open the GPIO protocol and return.
> > > > +     * If there is no match, repeat procedure with the next handle.
> > > > +     */
> > > > +    Status = MvGpioFindMatchingDriver (GpioDriverType,
> > > > +               HandleBuffer[Index],
> > > > +               DevicePath,
> > > > +               GpioProtocol);
> > > > +    if (Status == EFI_NOT_FOUND) {
> > > > +      continue;
> > > > +    } else if (EFI_ERROR (Status)) {
> > > > +      DEBUG ((DEBUG_ERROR,
> > > > +        "%a: Unable to open GPIO protocol\n",
> > > > +        __FUNCTION__));
> > > > +    }
> > > > +
> > > > +    gBS->FreePool (HandleBuffer);
> > > > +
> > > > +    return Status;
> > > > +  }
> > > > +
> > > > +  /* No matching GPIO protocol producer was found */
> > > > +  gBS->FreePool (HandleBuffer);
> > > > +
> > > > +  return EFI_NOT_FOUND;
> > > > +}
> > > > --
> > > > 2.7.4
> > > >


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2019-01-17 14:40 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-17 11:15 [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Marcin Wojtas
2019-01-17 11:15 ` [platforms: PATCH v3 01/12] Marvell/Library: ArmadaSoCDescLib: Add GPIO information Marcin Wojtas
2019-01-17 11:15 ` [platforms: PATCH v3 02/12] Marvell/Library: ArmadaBoardDescLib: " Marcin Wojtas
2019-01-17 11:15 ` [platforms: PATCH v3 03/12] Marvell/Library: Introduce MvGpioLib class Marcin Wojtas
2019-01-17 11:33   ` Leif Lindholm
2019-01-17 12:19     ` Marcin Wojtas
2019-01-17 14:18       ` Leif Lindholm
2019-01-17 14:39         ` Marcin Wojtas
2019-01-17 11:15 ` [platforms: PATCH v3 04/12] SolidRun/Armada80x0McBin: Extend board description library with GPIO Marcin Wojtas
2019-01-17 11:15 ` [platforms: PATCH v3 05/12] Marvell/Armada70x0Db: " Marcin Wojtas
2019-01-17 11:34   ` Leif Lindholm
2019-01-17 11:15 ` [platforms: PATCH v3 06/12] Marvell/Armada80x0Db: " Marcin Wojtas
2019-01-17 11:34   ` Leif Lindholm
2019-01-17 11:15 ` [platforms: PATCH v3 07/12] Marvell/Drivers: MvBoardDesc: Extend protocol with GPIO support Marcin Wojtas
2019-01-17 11:50   ` Leif Lindholm
2019-01-17 11:15 ` [platforms: PATCH v3 08/12] Marvell/Drivers: MvGpioDxe: Introduce platform GPIO driver Marcin Wojtas
2019-01-17 11:52   ` Leif Lindholm
2019-01-17 11:15 ` [platforms: PATCH v3 09/12] Marvell/Drivers: I2c: Use common header for macros Marcin Wojtas
2019-01-17 11:15 ` [platforms: PATCH v3 10/12] Marvell/Drivers: MvPca95xxDxe: Introduce GPIO expander driver Marcin Wojtas
2019-01-17 11:55   ` Leif Lindholm
2019-01-17 11:15 ` [platforms: PATCH v3 11/12] Marvell/Armada7k8k: Enable GPIO drivers compilation Marcin Wojtas
2019-01-17 11:15 ` [platforms: PATCH v3 12/12] Marvell/Armada7k8k: Introduce NonDiscoverable device init routines Marcin Wojtas
2019-01-17 12:03 ` [platforms: PATCH v3 00/12] Armada 7k8k GPIO support Leif Lindholm
2019-01-17 12:26   ` Marcin Wojtas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox