diff --git a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
index 196935b..f72d262 100644
--- a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
+++ b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
@@ -49,6 +49,14 @@ software, which makes signals float in the absence of pull up resistors.
 To fully drive output signals in either direction, enable push/pull mode
 for column pins.  This option is off by default for compatibility.
 
+The driver assumes that all interconnections of the matrix can potentially
+contain a button, and will submit scan and key code events to the input
+subsystem.  By default the keypad matrix dimenstions are automatically
+derived from the GPIO pin specifications.  Optionally device tree
+information can override the keypad matrix dimension data, e.g. when not
+all of the potentially available physical connections are used to create
+the logical keypad matrix.
+
 Required Properties:
 - compatible:		Should be "gpio-matrix-keypad"
 - row-gpios:		List of gpios used as row lines. The gpio specifier
@@ -88,6 +96,14 @@ Optional Properties:
 			behaviour is to actively drive low signals and
 			be passive otherwise (emulates an open collector
 			output driver)
+- keypad,num-rows:	number of rows in the keypad matrix, overrides the
+			value which gets derived from the number of row
+			GPIO pins, useful when not all lines are in use for
+			interconnects
+- keypad,num-columns:	number of columns in the keypad matrix, overrides
+			the value which gets derived from the number of
+			column GPIO pins, useful when not all lines are in
+			use for interconnects
 
 Example:
 	matrix-keypad {
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index c2221d1..30b7faf 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -111,7 +111,7 @@ static void activate_all_cols(const struct matrix_keypad_platform_data *pdata,
 {
 	int col;
 
-	for (col = 0; col < pdata->num_col_gpios; col++)
+	for (col = 0; col < pdata->num_matrix_cols; col++)
 		__activate_col_pin(pdata, col, on);
 }
 
@@ -142,7 +142,7 @@ static uint32_t sample_rows_for_col(struct matrix_keypad *keypad, int col)
 
 	activate_col(pdata, col, true);
 	row_state = 0;
-	for (row = 0; row < pdata->num_row_gpios; row++)
+	for (row = 0; row < pdata->num_matrix_rows; row++)
 		row_state |= row_asserted(pdata, row) ? (1 << row) : 0;
 	activate_col(pdata, col, false);
 
@@ -220,19 +220,19 @@ static void matrix_keypad_scan(struct work_struct *work)
 
 	/* assert each column in turn and read back the row status */
 	memset(new_state, 0, sizeof(new_state));
-	for (col = 0; col < pdata->num_col_gpios; col++)
+	for (col = 0; col < pdata->num_matrix_cols; col++)
 		new_state[col] = sample_rows_for_col(keypad, col);
 
 	/* detect changes and derive input events, update the snapshot */
 	has_events = 0;
-	for (col = 0; col < pdata->num_col_gpios; col++) {
+	for (col = 0; col < pdata->num_matrix_cols; col++) {
 		uint32_t bits_changed;
 
 		bits_changed = keypad->last_key_state[col] ^ new_state[col];
 		if (bits_changed == 0)
 			continue;
 
-		for (row = 0; row < pdata->num_row_gpios; row++) {
+		for (row = 0; row < pdata->num_matrix_rows; row++) {
 			if ((bits_changed & (1 << row)) == 0)
 				continue;
 
@@ -329,7 +329,7 @@ static void matrix_keypad_switch(struct work_struct *work)
 	 * compile time constants)
 	 */
 	keypad->col_to_poll++;
-	if (keypad->col_to_poll >= pdata->num_col_gpios)
+	if (keypad->col_to_poll >= pdata->num_matrix_cols)
 		keypad->col_to_poll = 0;
 	col = keypad->col_to_poll;
 
@@ -580,7 +580,8 @@ matrix_keypad_parse_dt(struct device *dev)
 	struct matrix_keypad_platform_data *pdata;
 	struct device_node *np = dev->of_node;
 	unsigned int *gpios;
-	int i, nrow, ncol;
+	int i;
+	int err;
 
 	if (!np) {
 		dev_err(dev, "device lacks DT data for the keypad config\n");
@@ -594,12 +595,18 @@ matrix_keypad_parse_dt(struct device *dev)
 	}
 
 	/* get the pin count for rows and columns */
-	pdata->num_row_gpios = nrow = of_gpio_named_count(np, "row-gpios");
-	pdata->num_col_gpios = ncol = of_gpio_named_count(np, "col-gpios");
-	if (nrow <= 0 || ncol <= 0) {
-		dev_err(dev, "number of keypad rows/columns not specified\n");
+	i = of_gpio_named_count(np, "row-gpios");
+	if (i <= 0) {
+		dev_err(dev, "row GPIO pin specs for keypad missing\n");
+		return ERR_PTR(-EINVAL);
+	}
+	pdata->num_row_gpios = i;
+	i = of_gpio_named_count(np, "col-gpios");
+	if (i <= 0) {
+		dev_err(dev, "column GPIO pin specs for keypad missing\n");
 		return ERR_PTR(-EINVAL);
 	}
+	pdata->num_col_gpios = i;
 
 	/* get input, power, and GPIO pin properties */
 	if (of_get_property(np, "linux,no-autorepeat", NULL))
@@ -644,6 +651,19 @@ matrix_keypad_parse_dt(struct device *dev)
 	pdata->row_gpios = gpios;
 	pdata->col_gpios = &gpios[pdata->num_row_gpios];
 
+	/*
+	 * auto determine the number of keypad matrix rows and columns
+	 * from the number of GPIO pins, optionally allow device tree
+	 * information to override these values
+	 */
+	pdata->num_matrix_rows = pdata->num_row_gpios;
+	pdata->num_matrix_cols = pdata->num_col_gpios;
+	err = matrix_keypad_parse_of_params(dev,
+					    &pdata->num_matrix_rows,
+					    &pdata->num_matrix_cols);
+	if (err)
+		return ERR_PTR(err);
+
 	return pdata;
 }
 #else
@@ -684,13 +704,13 @@ static int matrix_keypad_probe(struct platform_device *pdev)
 
 	keypad->input_dev = input_dev;
 	keypad->pdata = pdata;
-	keypad->row_shift = get_count_order(pdata->num_col_gpios);
+	keypad->row_shift = get_count_order(pdata->num_matrix_cols);
 
 	/* start in stopped state, open(2) will activate the scan */
 	keypad->stopped = true;
 	INIT_DELAYED_WORK(&keypad->work_scan_matrix, matrix_keypad_scan);
 	INIT_DELAYED_WORK(&keypad->work_switch_column, matrix_keypad_switch);
-	keypad->col_to_poll = pdata->num_col_gpios;
+	keypad->col_to_poll = pdata->num_matrix_cols;
 	spin_lock_init(&keypad->lock);
 
 	input_dev->name		= pdev->name;
@@ -700,8 +720,8 @@ static int matrix_keypad_probe(struct platform_device *pdev)
 	input_dev->close	= matrix_keypad_stop;
 
 	err = matrix_keypad_build_keymap(pdata->keymap_data, NULL,
-					 pdata->num_row_gpios,
-					 pdata->num_col_gpios,
+					 pdata->num_matrix_rows,
+					 pdata->num_matrix_cols,
 					 NULL, input_dev);
 	if (err) {
 		dev_err(&pdev->dev, "failed to build keymap\n");
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
index 3c8dc39..1398d23 100644
--- a/include/linux/input/matrix_keypad.h
+++ b/include/linux/input/matrix_keypad.h
@@ -39,6 +39,8 @@ struct matrix_keymap_data {
  * @col_gpios: pointer to array of gpio numbers reporesenting colums
  * @num_row_gpios: actual number of row gpios used by device
  * @num_col_gpios: actual number of col gpios used by device
+ * @num_matrix_rows: number of logical row lines in the matrix
+ * @num_matrix_cols: number of logical column lines in the matrix
  * @col_scan_delay_us: delay in microseconds, the interval between
  *	activating a column and reading back row information
  * @col_switch_delay_ms: delay in milliseconds, the interval with which
@@ -70,6 +72,10 @@ struct matrix_keypad_platform_data {
 	unsigned int	num_row_gpios;
 	unsigned int	num_col_gpios;
 
+	/* the logical matrix row/column lines */
+	unsigned int	num_matrix_rows;
+	unsigned int	num_matrix_cols;
+
 	/* delays and intervals specs */
 	unsigned int	col_scan_delay_us;
 	unsigned int	col_switch_delay_ms;
