Unverified Commit 775dea4d authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'ixp4xx-drivers-arm-soc-v5.15-1' of...

Merge tag 'ixp4xx-drivers-arm-soc-v5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik into arm/drivers

IXP4xx driver updates for modernizing the IXP4xx platforms,
taregeted for v5.15:

- Add DT bindings to the expansion bus and PATA libata driver.

- Add a new expansion bus driver.

- Rewrite the watchdog driver to use the watchdog core and
  spawn from the timer (clocksource) driver.

- Refactor the PATA/libata driver to probe from the device
  tree and use the expansion bus driver to manipulate chip
  select timings directly.

* tag 'ixp4xx-drivers-arm-soc-v5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik:
  pata: ixp4xx: Rewrite to use device tree
  pata: ixp4xx: Add DT bindings
  pata: ixp4xx: Refer to cmd and ctl rather than csN
  pata: ixp4xx: Use IS_ENABLED() to determine endianness
  pata: ixp4xx: Use local dev variable
  watchdog: ixp4xx: Rewrite driver to use core
  bus: ixp4xx: Add a driver for IXP4xx expansion bus
  bus: ixp4xx: Add DT bindings for the IXP4xx expansion bus

Link: https://lore.kernel.org/r/CACRpkdZaCosXsgp02nuUbd_nEvdxm5-z0+d0oSA97UTWQ0RQQg@mail.gmail.com


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents b6e952c3 47adef20
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/ata/intel,ixp4xx-compact-flash.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Intel IXP4xx CompactFlash Card Controller

maintainers:
  - Linus Walleij <linus.walleij@linaro.org>

description: |
  The IXP4xx network processors have a CompactFlash interface that presents
  a CompactFlash card to the system as a true IDE (parallel ATA) device. The
  device is always connected to the expansion bus of the IXP4xx SoCs using one
  or two chip select areas and address translating logic on the board. The
  node must be placed inside a chip select node on the IXP4xx expansion bus.

properties:
  compatible:
    const: intel,ixp4xx-compact-flash

  reg:
    items:
      - description: Command interface registers
      - description: Control interface registers

  interrupts:
    maxItems: 1

required:
  - compatible
  - reg
  - interrupts

allOf:
  - $ref: pata-common.yaml#

unevaluatedProperties: false

examples:
  - |
    #include <dt-bindings/interrupt-controller/irq.h>

    bus@c4000000 {
      compatible = "intel,ixp43x-expansion-bus-controller", "syscon";
      reg = <0xc4000000 0x1000>;
      native-endian;
      #address-cells = <2>;
      #size-cells = <1>;
      ranges = <0 0x0 0x50000000 0x01000000>, <1 0x0 0x51000000 0x01000000>;
      dma-ranges = <0 0x0 0x50000000 0x01000000>, <1 0x0 0x51000000 0x01000000>;
      ide@1,0 {
        compatible = "intel,ixp4xx-compact-flash";
        reg = <1 0x00000000 0x1000>, <1 0x00040000 0x1000>;
        interrupt-parent = <&gpio0>;
        interrupts = <12 IRQ_TYPE_EDGE_RISING>;
      };
    };

...
+168 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/bus/intel,ixp4xx-expansion-bus-controller.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Intel IXP4xx Expansion Bus Controller

description: |
  The IXP4xx expansion bus controller handles access to devices on the
  memory-mapped expansion bus on the Intel IXP4xx family of system on chips,
  including IXP42x, IXP43x, IXP45x and IXP46x.

maintainers:
  - Linus Walleij <linus.walleij@linaro.org>

properties:
  $nodename:
    pattern: '^bus@[0-9a-f]+$'

  compatible:
    items:
      - enum:
          - intel,ixp42x-expansion-bus-controller
          - intel,ixp43x-expansion-bus-controller
          - intel,ixp45x-expansion-bus-controller
          - intel,ixp46x-expansion-bus-controller
      - const: syscon

  reg:
    description: Control registers for the expansion bus, these are not
      inside the memory range handled by the expansion bus.
    maxItems: 1

  native-endian:
    $ref: /schemas/types.yaml#/definitions/flag
    description: The IXP4xx has a peculiar MMIO access scheme, as it changes
      the access pattern for words (swizzling) on the bus depending on whether
      the SoC is running in big-endian or little-endian mode. Thus the
      registers must always be accessed using native endianness.

  "#address-cells":
    description: |
      The first cell is the chip select number.
      The second cell is the address offset within the bank.
    const: 2

  "#size-cells":
    const: 1

  ranges: true
  dma-ranges: true

patternProperties:
  "^.*@[0-7],[0-9a-f]+$":
    description: Devices attached to chip selects are represented as
      subnodes.
    type: object

    properties:
      intel,ixp4xx-eb-t1:
        description: Address timing, extend address phase with n cycles.
        $ref: /schemas/types.yaml#/definitions/uint32
        maximum: 3

      intel,ixp4xx-eb-t2:
        description: Setup chip select timing, extend setup phase with n cycles.
        $ref: /schemas/types.yaml#/definitions/uint32
        maximum: 3

      intel,ixp4xx-eb-t3:
        description: Strobe timing, extend strobe phase with n cycles.
        $ref: /schemas/types.yaml#/definitions/uint32
        maximum: 15

      intel,ixp4xx-eb-t4:
        description: Hold timing, extend hold phase with n cycles.
        $ref: /schemas/types.yaml#/definitions/uint32
        maximum: 3

      intel,ixp4xx-eb-t5:
        description: Recovery timing, extend recovery phase with n cycles.
        $ref: /schemas/types.yaml#/definitions/uint32
        maximum: 15

      intel,ixp4xx-eb-cycle-type:
        description: The type of cycles to use on the expansion bus for this
          chip select. 0 = Intel cycles, 1 = Motorola cycles, 2 = HPI cycles.
        $ref: /schemas/types.yaml#/definitions/uint32
        enum: [0, 1, 2]

      intel,ixp4xx-eb-byte-access-on-halfword:
        description: Allow byte read access on half word devices.
        $ref: /schemas/types.yaml#/definitions/uint32
        enum: [0, 1]

      intel,ixp4xx-eb-hpi-hrdy-pol-high:
        description: Set HPI HRDY polarity to active high when using HPI.
        $ref: /schemas/types.yaml#/definitions/uint32
        enum: [0, 1]

      intel,ixp4xx-eb-mux-address-and-data:
        description: Multiplex address and data on the data bus.
        $ref: /schemas/types.yaml#/definitions/uint32
        enum: [0, 1]

      intel,ixp4xx-eb-ahb-split-transfers:
        description: Enable AHB split transfers.
        $ref: /schemas/types.yaml#/definitions/uint32
        enum: [0, 1]

      intel,ixp4xx-eb-write-enable:
        description: Enable write cycles.
        $ref: /schemas/types.yaml#/definitions/uint32
        enum: [0, 1]

      intel,ixp4xx-eb-byte-access:
        description: Expansion bus uses only 8 bits. The default is to use
          16 bits.
        $ref: /schemas/types.yaml#/definitions/uint32
        enum: [0, 1]

required:
  - compatible
  - reg
  - native-endian
  - "#address-cells"
  - "#size-cells"
  - ranges
  - dma-ranges

additionalProperties: false

examples:
  - |
    #include <dt-bindings/interrupt-controller/irq.h>
    bus@50000000 {
        compatible = "intel,ixp42x-expansion-bus-controller", "syscon";
        reg = <0xc4000000 0x28>;
        native-endian;
        #address-cells = <2>;
        #size-cells = <1>;
        ranges = <0 0x0 0x50000000 0x01000000>,
                 <1 0x0 0x51000000 0x01000000>;
        dma-ranges = <0 0x0 0x50000000 0x01000000>,
                     <1 0x0 0x51000000 0x01000000>;
        flash@0,0 {
            compatible = "intel,ixp4xx-flash", "cfi-flash";
            bank-width = <2>;
            reg = <0 0x00000000 0x1000000>;
            intel,ixp4xx-eb-t3 = <3>;
            intel,ixp4xx-eb-cycle-type = <0>;
            intel,ixp4xx-eb-byte-access-on-halfword = <1>;
            intel,ixp4xx-eb-write-enable = <1>;
            intel,ixp4xx-eb-byte-access = <0>;
        };
        serial@1,0 {
            compatible = "exar,xr16l2551", "ns8250";
            reg = <1 0x00000000 0x10>;
            interrupt-parent = <&gpio0>;
            interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
            clock-frequency = <1843200>;
            intel,ixp4xx-eb-t3 = <3>;
            intel,ixp4xx-eb-cycle-type = <1>;
            intel,ixp4xx-eb-write-enable = <1>;
            intel,ixp4xx-eb-byte-access = <1>;
        };
    };
+2 −0
Original line number Diff line number Diff line
@@ -2010,10 +2010,12 @@ M: Krzysztof Halasa <khalasa@piap.pl>
L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S:	Maintained
F:	Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
F:	Documentation/devicetree/bindings/bus/intel,ixp4xx-expansion-bus-controller.yaml
F:	Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt
F:	Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
F:	Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml
F:	arch/arm/mach-ixp4xx/
F:	drivers/bus/intel-ixp4xx-eb.c
F:	drivers/clocksource/timer-ixp4xx.c
F:	drivers/crypto/ixp4xx_crypto.c
F:	drivers/gpio/gpio-ixp4xx.c
+185 −79
Original line number Diff line number Diff line
@@ -13,45 +13,134 @@
 */

#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/libata.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/platform_data/pata_ixp4xx_cf.h>
#include <linux/regmap.h>
#include <scsi/scsi_host.h>

#define DRV_NAME	"pata_ixp4xx_cf"
#define DRV_VERSION	"0.2"
#define DRV_VERSION	"1.0"

static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error)
struct ixp4xx_pata {
	struct ata_host *host;
	struct regmap *rmap;
	u32 cmd_csreg;
	void __iomem *cmd;
	void __iomem *ctl;
};

#define IXP4XX_EXP_TIMING_STRIDE	0x04
/* The timings for the chipselect is in bits 29..16 */
#define IXP4XX_EXP_T1_T5_MASK	GENMASK(29, 16)
#define IXP4XX_EXP_PIO_0_8	0x0a470000
#define IXP4XX_EXP_PIO_1_8	0x06430000
#define IXP4XX_EXP_PIO_2_8	0x02410000
#define IXP4XX_EXP_PIO_3_8	0x00820000
#define IXP4XX_EXP_PIO_4_8	0x00400000
#define IXP4XX_EXP_PIO_0_16	0x29640000
#define IXP4XX_EXP_PIO_1_16	0x05030000
#define IXP4XX_EXP_PIO_2_16	0x00b20000
#define IXP4XX_EXP_PIO_3_16	0x00820000
#define IXP4XX_EXP_PIO_4_16	0x00400000
#define IXP4XX_EXP_BW_MASK	(BIT(6)|BIT(0))
#define IXP4XX_EXP_BYTE_RD16	BIT(6) /* Byte reads on half-word devices */
#define IXP4XX_EXP_BYTE_EN	BIT(0) /* Use 8bit data bus if set */

static void ixp4xx_set_8bit_timing(struct ixp4xx_pata *ixpp, u8 pio_mode)
{
	switch (pio_mode) {
	case XFER_PIO_0:
		regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
				   IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_0_8);
		break;
	case XFER_PIO_1:
		regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
				   IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_1_8);
		break;
	case XFER_PIO_2:
		regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
				   IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_2_8);
		break;
	case XFER_PIO_3:
		regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
				   IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_3_8);
		break;
	case XFER_PIO_4:
		regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
				   IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_4_8);
		break;
	default:
		break;
	}
	regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
			   IXP4XX_EXP_BW_MASK, IXP4XX_EXP_BYTE_RD16|IXP4XX_EXP_BYTE_EN);
}

static void ixp4xx_set_16bit_timing(struct ixp4xx_pata *ixpp, u8 pio_mode)
{
	struct ata_device *dev;

	ata_for_each_dev(dev, link, ENABLED) {
		ata_dev_info(dev, "configured for PIO0\n");
		dev->pio_mode = XFER_PIO_0;
		dev->xfer_mode = XFER_PIO_0;
		dev->xfer_shift = ATA_SHIFT_PIO;
		dev->flags |= ATA_DFLAG_PIO;
	switch (pio_mode){
	case XFER_PIO_0:
		regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
				   IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_0_16);
		break;
	case XFER_PIO_1:
		regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
				   IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_1_16);
		break;
	case XFER_PIO_2:
		regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
				   IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_2_16);
		break;
	case XFER_PIO_3:
		regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
				   IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_3_16);
		break;
	case XFER_PIO_4:
		regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
				   IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_4_16);
		break;
	default:
		break;
	}
	return 0;
	regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg,
			   IXP4XX_EXP_BW_MASK, IXP4XX_EXP_BYTE_RD16);
}

/* This sets up the timing on the chipselect CMD accordingly */
static void ixp4xx_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
	struct ixp4xx_pata *ixpp = ap->host->private_data;

	ata_dev_printk(adev, KERN_INFO, "configured for PIO%d 8bit\n",
		       adev->pio_mode - XFER_PIO_0);
	ixp4xx_set_8bit_timing(ixpp, adev->pio_mode);
}


static unsigned int ixp4xx_mmio_data_xfer(struct ata_queued_cmd *qc,
					  unsigned char *buf, unsigned int buflen, int rw)
{
	unsigned int i;
	unsigned int words = buflen >> 1;
	u16 *buf16 = (u16 *) buf;
	struct ata_device *adev = qc->dev;
	struct ata_port *ap = qc->dev->link->ap;
	void __iomem *mmio = ap->ioaddr.data_addr;
	struct ixp4xx_pata_data *data = dev_get_platdata(ap->host->dev);
	struct ixp4xx_pata *ixpp = ap->host->private_data;
	unsigned long flags;

	ata_dev_printk(adev, KERN_DEBUG, "%s %d bytes\n", (rw == READ) ? "READ" : "WRITE",
		       buflen);
	spin_lock_irqsave(ap->lock, flags);

	/* set the expansion bus in 16bit mode and restore
	 * 8 bit mode after the transaction.
	 */
	*data->cs0_cfg &= ~(0x01);
	udelay(100);
	ixp4xx_set_16bit_timing(ixpp, adev->pio_mode);
	udelay(5);

	/* Transfer multiple of 2 bytes */
	if (rw == READ)
@@ -76,8 +165,10 @@ static unsigned int ixp4xx_mmio_data_xfer(struct ata_queued_cmd *qc,
		words++;
	}

	udelay(100);
	*data->cs0_cfg |= 0x01;
	ixp4xx_set_8bit_timing(ixpp, adev->pio_mode);
	udelay(5);

	spin_unlock_irqrestore(ap->lock, flags);

	return words << 1;
}
@@ -90,25 +181,29 @@ static struct ata_port_operations ixp4xx_port_ops = {
	.inherits		= &ata_sff_port_ops,
	.sff_data_xfer		= ixp4xx_mmio_data_xfer,
	.cable_detect		= ata_cable_40wire,
	.set_mode		= ixp4xx_set_mode,
	.set_piomode		= ixp4xx_set_piomode,
};

static struct ata_port_info ixp4xx_port_info = {
	.flags		= ATA_FLAG_NO_ATAPI,
	.pio_mask	= ATA_PIO4,
	.port_ops	= &ixp4xx_port_ops,
};

static void ixp4xx_setup_port(struct ata_port *ap,
			      struct ixp4xx_pata_data *data,
			      unsigned long raw_cs0, unsigned long raw_cs1)
			      struct ixp4xx_pata *ixpp,
			      unsigned long raw_cmd, unsigned long raw_ctl)
{
	struct ata_ioports *ioaddr = &ap->ioaddr;
	unsigned long raw_cmd = raw_cs0;
	unsigned long raw_ctl = raw_cs1 + 0x06;

	ioaddr->cmd_addr	= data->cs0;
	ioaddr->altstatus_addr	= data->cs1 + 0x06;
	ioaddr->ctl_addr	= data->cs1 + 0x06;
	raw_ctl += 0x06;
	ioaddr->cmd_addr	= ixpp->cmd;
	ioaddr->altstatus_addr	= ixpp->ctl + 0x06;
	ioaddr->ctl_addr	= ixpp->ctl + 0x06;

	ata_sff_std_ports(ioaddr);

#ifndef __ARMEB__

	if (!IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) {
		/* adjust the addresses to handle the address swizzling of the
		 * ixp4xx in little endian mode.
		 */
@@ -129,40 +224,55 @@ static void ixp4xx_setup_port(struct ata_port *ap,

		raw_cmd ^= 0x03;
		raw_ctl ^= 0x03;
#endif
	}

	ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", raw_cmd, raw_ctl);
}

static int ixp4xx_pata_probe(struct platform_device *pdev)
{
	struct resource *cs0, *cs1;
	struct ata_host *host;
	struct ata_port *ap;
	struct ixp4xx_pata_data *data = dev_get_platdata(&pdev->dev);
	struct resource *cmd, *ctl;
	struct ata_port_info pi = ixp4xx_port_info;
	const struct ata_port_info *ppi[] = { &pi, NULL };
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct ixp4xx_pata *ixpp;
	u32 csindex;
	int ret;
	int irq;

	cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	cmd = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	ctl = platform_get_resource(pdev, IORESOURCE_MEM, 1);

	if (!cs0 || !cs1)
	if (!cmd || !ctl)
		return -EINVAL;

	/* allocate host */
	host = ata_host_alloc(&pdev->dev, 1);
	if (!host)
	ixpp = devm_kzalloc(dev, sizeof(*ixpp), GFP_KERNEL);
	if (!ixpp)
		return -ENOMEM;

	/* acquire resources and fill host */
	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
	ixpp->rmap = syscon_node_to_regmap(np->parent);
	if (IS_ERR(ixpp->rmap))
		return dev_err_probe(dev, PTR_ERR(ixpp->rmap), "no regmap\n");
	/* Inspect our address to figure out what chipselect the CMD is on */
	ret = of_property_read_u32_index(np, "reg", 0, &csindex);
	if (ret)
		return ret;
		return dev_err_probe(dev, ret, "can't inspect CMD address\n");
	dev_info(dev, "using CS%d for PIO timing configuration\n", csindex);
	ixpp->cmd_csreg = csindex * IXP4XX_EXP_TIMING_STRIDE;

	ixpp->host = ata_host_alloc_pinfo(dev, ppi, 1);
	if (!ixpp->host)
		return -ENOMEM;
	ixpp->host->private_data = ixpp;

	data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
	data->cs1 = devm_ioremap(&pdev->dev, cs1->start, 0x1000);
	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
	if (ret)
		return ret;

	if (!data->cs0 || !data->cs1)
	ixpp->cmd = devm_ioremap_resource(dev, cmd);
	ixpp->ctl = devm_ioremap_resource(dev, ctl);
	if (IS_ERR(ixpp->cmd) || IS_ERR(ixpp->ctl))
		return -ENOMEM;

	irq = platform_get_irq(pdev, 0);
@@ -173,27 +283,23 @@ static int ixp4xx_pata_probe(struct platform_device *pdev)
	else
		return -EINVAL;

	/* Setup expansion bus chip selects */
	*data->cs0_cfg = data->cs0_bits;
	*data->cs1_cfg = data->cs1_bits;

	ap = host->ports[0];

	ap->ops	= &ixp4xx_port_ops;
	ap->pio_mask = ATA_PIO4;
	ap->flags |= ATA_FLAG_NO_ATAPI;
	/* Just one port to set up */
	ixp4xx_setup_port(ixpp->host->ports[0], ixpp, cmd->start, ctl->start);

	ixp4xx_setup_port(ap, data, cs0->start, cs1->start);
	ata_print_version_once(dev, DRV_VERSION);

	ata_print_version_once(&pdev->dev, DRV_VERSION);

	/* activate host */
	return ata_host_activate(host, irq, ata_sff_interrupt, 0, &ixp4xx_sht);
	return ata_host_activate(ixpp->host, irq, ata_sff_interrupt, 0, &ixp4xx_sht);
}

static const struct of_device_id ixp4xx_pata_of_match[] = {
	{ .compatible = "intel,ixp4xx-compact-flash", },
	{ },
};

static struct platform_driver ixp4xx_pata_platform_driver = {
	.driver	 = {
		.name   = DRV_NAME,
		.of_match_table = ixp4xx_pata_of_match,
	},
	.probe		= ixp4xx_pata_probe,
	.remove		= ata_platform_remove_one,
+11 −0
Original line number Diff line number Diff line
@@ -95,6 +95,17 @@ config IMX_WEIM
	  The WEIM(Wireless External Interface Module) works like a bus.
	  You can attach many different devices on it, such as NOR, onenand.

config INTEL_IXP4XX_EB
	bool "Intel IXP4xx expansion bus interface driver"
	depends on HAS_IOMEM
	depends on ARCH_IXP4XX || COMPILE_TEST
	default ARCH_IXP4XX
	select MFD_SYSCON
	help
	  Driver for the Intel IXP4xx expansion bus interface. The driver is
	  needed to set up various chip select configuration parameters before
	  devices on the expansion bus can be discovered.

config MIPS_CDMM
	bool "MIPS Common Device Memory Map (CDMM) Driver"
	depends on CPU_MIPSR2 || CPU_MIPSR5
Loading