@@ -41,6 +41,7 @@
/**
* struct xgpio_instance - Stores information about GPIO device
* @mmchip: OF GPIO chip for memory mapped banks
+ * @no_init: No intitialisation at probe
* @gpio_width: GPIO width for every channel
* @gpio_state: GPIO state shadow register
* @gpio_dir: GPIO direction shadow register
@@ -48,6 +49,7 @@
*/
struct xgpio_instance {
struct of_mm_gpio_chip mmchip;
+ bool no_init;
unsigned int gpio_width[2];
u32 gpio_state[2];
u32 gpio_dir[2];
@@ -257,16 +259,36 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
struct xgpio_instance *chip =
container_of(mm_gc, struct xgpio_instance, mmchip);
- xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state[0]);
- xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
-
- if (!chip->gpio_width[1])
- return;
-
- xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
- chip->gpio_state[1]);
- xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
- chip->gpio_dir[1]);
+ if (chip->no_init) {
+ chip->gpio_state[0] = xgpio_readreg(mm_gc->regs +
+ XGPIO_DATA_OFFSET);
+ chip->gpio_dir[0] = xgpio_readreg(mm_gc->regs +
+ XGPIO_TRI_OFFSET);
+
+ if (!chip->gpio_width[1])
+ return;
+
+ chip->gpio_state[1] = xgpio_readreg(mm_gc->regs +
+ XGPIO_DATA_OFFSET +
+ XGPIO_CHANNEL_OFFSET);
+ chip->gpio_dir[1] = xgpio_readreg(mm_gc->regs +
+ XGPIO_TRI_OFFSET +
+ XGPIO_CHANNEL_OFFSET);
+
+ } else {
+ xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET,
+ chip->gpio_state[0]);
+ xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET,
+ chip->gpio_dir[0]);
+
+ if (!chip->gpio_width[1])
+ return;
+
+ xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
+ XGPIO_CHANNEL_OFFSET, chip->gpio_state[1]);
+ xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET +
+ XGPIO_CHANNEL_OFFSET, chip->gpio_dir[1]);
+ }
}
/**
@@ -323,6 +345,8 @@ static int xgpio_probe(struct platform_device *pdev)
spin_lock_init(&chip->gpio_lock[0]);
+ chip->no_init = of_property_read_bool(np, "xlnx,no-init");
+
if (of_property_read_u32(np, "xlnx,is-dual", &is_dual))
is_dual = 0;