<html><body><p>Will the old gpio #'s still work with this?   Can I export by gpio pin name?  echo "A3" > /sys/class/gpio/export?<br><br><br><img width="16" height="16" src="cid:1__=09BBF478DFDA643B8f9e8a93df938690918c09B@" border="0" alt="Inactive hide details for OpenBMC Patches ---10/27/2015 08:14:50 AM---From: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Jeremy K"><font color="#424282">OpenBMC Patches ---10/27/2015 08:14:50 AM---From: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Jeremy Kerr <jk@ozlabs.org></font><br><br><font size="2" color="#5F5F5F">From:        </font><font size="2">OpenBMC Patches <patches@stwcx.xyz></font><br><font size="2" color="#5F5F5F">To:        </font><font size="2">openbmc@lists.ozlabs.org</font><br><font size="2" color="#5F5F5F">Date:        </font><font size="2">10/27/2015 08:14 AM</font><br><font size="2" color="#5F5F5F">Subject:        </font><font size="2">[PATCH linux 2/3] gpio/aspeed: Expose entire bank as one gpio chip</font><br><font size="2" color="#5F5F5F">Sent by:        </font><font size="2">"openbmc" <openbmc-bounces+njames=us.ibm.com@lists.ozlabs.org></font><br><hr width="100%" size="2" align="left" noshade style="color:#8091A5; "><br><br><br><tt>From: Jeremy Kerr <jk@ozlabs.org><br><br>Signed-off-by: Jeremy Kerr <jk@ozlabs.org><br>---<br> arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts |  29 +------<br> drivers/gpio/gpio-aspeed.c                    | 106 +++++++++++++++++++++++---<br> 2 files changed, 98 insertions(+), 37 deletions(-)<br><br>diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts<br>index d90e4ba..e63ddb9 100644<br>--- a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts<br>+++ b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts<br>@@ -145,34 +145,9 @@<br>                                                                     clocks = <&clk_apb>;<br>                                                    };<br> <br>-                                                   gpio0: gpio@1e780000 {<br>+                                                   gpio: gpio@1e780000 {<br>                                                           compatible = "aspeed,ast2400-gpio";<br>-                                                          reg = <0x1e780000 0x20>;<br>-                                                   };<br>-<br>-                                                   gpio1: gpio@1e780020 {<br>-                                                          compatible = "aspeed,ast2400-gpio";<br>-                                                          reg = <0x1e780020 0x20>;<br>-                                                   };<br>-<br>-                                                   gpio2: gpio@1e780070 {<br>-                                                          compatible = "aspeed,ast2400-gpio";<br>-                                                          reg = <0x1e780070 0x8>;<br>-                                                   };<br>-<br>-                                                   gpio3: gpio@1e780078 {<br>-                                                          compatible = "aspeed,ast2400-gpio";<br>-                                                          reg = <0x1e780078 0x8>;<br>-                                                   };<br>-<br>-                                                   gpio4: gpio@1e780080 {<br>-                                                          compatible = "aspeed,ast2400-gpio";<br>-                                                          reg = <0x1e780080 0x8>;<br>-                                                   };<br>-<br>-                                                   gpio5: gpio@1e780088 {<br>-                                                          compatible = "aspeed,ast2400-gpio";<br>-                                                          reg = <0x1e780088 0x8>;<br>+                                                          reg = <0x1e780000 0x1000>;<br>                                                    };<br> <br>                                                    uart1: serial@1e783000 {<br>diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c<br>index f347260..8295371 100644<br>--- a/drivers/gpio/gpio-aspeed.c<br>+++ b/drivers/gpio/gpio-aspeed.c<br>@@ -23,6 +23,42 @@ struct aspeed_gpio {<br>                  void __iomem *base;<br> };<br> <br>+struct aspeed_gpio_bank {<br>+                 uint16_t                 val_regs;<br>+                 char                                  names[4];<br>+};<br>+<br>+static struct aspeed_gpio_bank aspeed_gpio_banks[] = {<br>+                 {<br>+                                  .val_regs = 0x0000,<br>+                                  .names = { 'A', 'B', 'C', 'D' },<br>+                 },<br>+                 {<br>+                                  .val_regs = 0x0020,<br>+                                  .names = { 'E', 'F', 'G', 'H' },<br>+                 },<br>+                 {<br>+                                  .val_regs = 0x0070,<br>+                                  .names = { 'I', 'J', 'K', 'L' },<br>+                 },<br>+                 {<br>+                                  .val_regs = 0x0078,<br>+                                  .names = { 'M', 'N', 'O', 'P' },<br>+                 },<br>+                 {<br>+                                  .val_regs = 0x0080,<br>+                                  .names = { 'Q', 'R', 'S', 'T' },<br>+                 },<br>+                 {<br>+                                  .val_regs = 0x0088,<br>+                                  .names = { 'U', 'V', 'W', 'X' },<br>+                 },<br>+};<br>+<br>+#define GPIO_BANK(x)                 ((x) >> 5)<br>+#define GPIO_OFFSET(x)                 ((x) & 0x1f)<br>+#define GPIO_BIT(x)                 BIT(GPIO_OFFSET(x))<br>+<br> #define GPIO_DATA                 0x00<br> #define GPIO_DIR                 0x04<br> <br>@@ -31,29 +67,46 @@ static inline struct aspeed_gpio *to_aspeed_gpio(struct gpio_chip *chip)<br>                  return container_of(chip, struct aspeed_gpio, chip);<br> }<br> <br>+static struct aspeed_gpio_bank *to_bank(unsigned int offset)<br>+{<br>+                 unsigned int bank = GPIO_BANK(offset);<br>+                 WARN_ON(bank > ARRAY_SIZE(aspeed_gpio_banks));<br>+                 return &aspeed_gpio_banks[bank];<br>+}<br>+<br>+static void *bank_val_reg(struct aspeed_gpio *gpio,<br>+                                  struct aspeed_gpio_bank *bank,<br>+                                  unsigned int reg)<br>+{<br>+                 return gpio->base + bank->val_regs + reg;<br>+}<br>+<br> static int aspeed_gpio_get(struct gpio_chip *gc, unsigned int offset)<br> {<br>                  struct aspeed_gpio *gpio = to_aspeed_gpio(gc);<br>+                 struct aspeed_gpio_bank *bank = to_bank(offset);<br> <br>-                 return !!(ioread32(gpio->base + GPIO_DATA) & BIT(offset));<br>+                 return !!(ioread32(bank_val_reg(gpio, bank, GPIO_DATA))<br>+                                                   & GPIO_BIT(offset));<br> }<br> <br> static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,<br>                                                        int val)<br> {<br>                  struct aspeed_gpio *gpio = to_aspeed_gpio(gc);<br>+                 struct aspeed_gpio_bank *bank = to_bank(offset);<br>                  unsigned long flags;<br>                  u32 reg;<br> <br>                  spin_lock_irqsave(&gpio->lock, flags);<br> <br>-                 reg = ioread32(gpio->base + GPIO_DATA);<br>+                 reg = ioread32(bank_val_reg(gpio, bank, GPIO_DATA));<br>                  if (val)<br>-                                  reg |= BIT(offset);<br>+                                  reg |= GPIO_BIT(offset);<br>                  else<br>-                                  reg &= ~BIT(offset);<br>+                                  reg &= ~GPIO_BIT(offset);<br> <br>-                 iowrite32(reg, gpio->base + GPIO_DATA);<br>+                 iowrite32(reg, bank_val_reg(gpio, bank, GPIO_DATA));<br> <br>                  spin_unlock_irqrestore(&gpio->lock, flags);<br> }<br>@@ -61,13 +114,14 @@ static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,<br> static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)<br> {<br>                  struct aspeed_gpio *gpio = to_aspeed_gpio(gc);<br>+                 struct aspeed_gpio_bank *bank = to_bank(offset);<br>                  unsigned long flags;<br>                  u32 reg;<br> <br>                  spin_lock_irqsave(&gpio->lock, flags);<br> <br>-                 reg = ioread32(gpio->base + GPIO_DIR);<br>-                 iowrite32(reg & ~BIT(offset), gpio->base + GPIO_DIR);<br>+                 reg = ioread32(bank_val_reg(gpio, bank, GPIO_DIR));<br>+                 iowrite32(reg & ~GPIO_BIT(offset), bank_val_reg(gpio, bank, GPIO_DIR));<br> <br>                  spin_unlock_irqrestore(&gpio->lock, flags);<br> <br>@@ -78,19 +132,49 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,<br>                                                           unsigned int offset, int val)<br> {<br>                  struct aspeed_gpio *gpio = to_aspeed_gpio(gc);<br>+                 struct aspeed_gpio_bank *bank = to_bank(offset);<br>                  unsigned long flags;<br>                  u32 reg;<br> <br>                  spin_lock_irqsave(&gpio->lock, flags);<br> <br>-                 reg = ioread32(gpio->base + GPIO_DIR);<br>-                 iowrite32(reg | BIT(offset), gpio->base + GPIO_DIR);<br>+                 reg = ioread32(bank_val_reg(gpio, bank, GPIO_DIR));<br>+                 iowrite32(reg | GPIO_BIT(offset), bank_val_reg(gpio, bank, GPIO_DIR));<br> <br>                  spin_unlock_irqrestore(&gpio->lock, flags);<br> <br>                  return 0;<br> }<br> <br>+static void aspeed_gpio_set_names(struct aspeed_gpio *gpio)<br>+{<br>+                 const char format[] = "GPIOXn";<br>+                 char *namebuf, **names;<br>+                 unsigned int i;<br>+<br>+                 /* our buffer of name pointers */<br>+                 names = devm_kmalloc_array(gpio->chip.dev, gpio->chip.ngpio,<br>+                                                   sizeof(char *), GFP_KERNEL);<br>+<br>+                 /* and one contiguous buffer for the names themselves */<br>+                 namebuf = devm_kmalloc_array(gpio->chip.dev, gpio->chip.ngpio,<br>+                                                   sizeof(format), GFP_KERNEL);<br>+<br>+                 for (i = 0; i < gpio->chip.ngpio; i++) {<br>+                                  struct aspeed_gpio_bank *bank = to_bank(i);<br>+                                  char *name = namebuf + (i * sizeof(format));<br>+                                  int bit = GPIO_OFFSET(i);<br>+<br>+                                  memcpy(name, format, 4);<br>+                                  name[4] = bank->names[bit >> 3];<br>+                                  name[5] = '0' + (bit % 8);<br>+                                  name[6] = '\0';<br>+                                  names[i] = name;<br>+                 }<br>+<br>+                 gpio->chip.names = (const char * const *)names;<br>+}<br>+<br> static int __init aspeed_gpio_probe(struct platform_device *pdev)<br> {<br>                  struct resource *res;<br>@@ -110,7 +194,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)<br> <br>                  spin_lock_init(&gpio->lock);<br> <br>-                 gpio->chip.ngpio = 32;<br>+                 gpio->chip.ngpio = ARRAY_SIZE(aspeed_gpio_banks) * 32;<br> <br>                  gpio->chip.dev = &pdev->dev;<br>                  gpio->chip.direction_input = aspeed_gpio_dir_in;<br>@@ -120,6 +204,8 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)<br>                  gpio->chip.label = dev_name(&pdev->dev);<br>                  gpio->chip.base = -1;<br> <br>+                 aspeed_gpio_set_names(gpio);<br>+<br>                  platform_set_drvdata(pdev, gpio);<br> <br>                  return gpiochip_add(&gpio->chip);<br>-- <br>2.6.0<br><br><br>_______________________________________________<br>openbmc mailing list<br>openbmc@lists.ozlabs.org<br></tt><tt><a href="https://lists.ozlabs.org/listinfo/openbmc">https://lists.ozlabs.org/listinfo/openbmc</a></tt><tt><br></tt><br><BR>
</body></html>