Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Arnd Bergmann <arnd@arndb.de>

+1028 -272
+61
Documentation/devicetree/bindings/ata/intel,ixp4xx-compact-flash.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/ata/intel,ixp4xx-compact-flash.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Intel IXP4xx CompactFlash Card Controller 8 + 9 + maintainers: 10 + - Linus Walleij <linus.walleij@linaro.org> 11 + 12 + description: | 13 + The IXP4xx network processors have a CompactFlash interface that presents 14 + a CompactFlash card to the system as a true IDE (parallel ATA) device. The 15 + device is always connected to the expansion bus of the IXP4xx SoCs using one 16 + or two chip select areas and address translating logic on the board. The 17 + node must be placed inside a chip select node on the IXP4xx expansion bus. 18 + 19 + properties: 20 + compatible: 21 + const: intel,ixp4xx-compact-flash 22 + 23 + reg: 24 + items: 25 + - description: Command interface registers 26 + - description: Control interface registers 27 + 28 + interrupts: 29 + maxItems: 1 30 + 31 + required: 32 + - compatible 33 + - reg 34 + - interrupts 35 + 36 + allOf: 37 + - $ref: pata-common.yaml# 38 + 39 + unevaluatedProperties: false 40 + 41 + examples: 42 + - | 43 + #include <dt-bindings/interrupt-controller/irq.h> 44 + 45 + bus@c4000000 { 46 + compatible = "intel,ixp43x-expansion-bus-controller", "syscon"; 47 + reg = <0xc4000000 0x1000>; 48 + native-endian; 49 + #address-cells = <2>; 50 + #size-cells = <1>; 51 + ranges = <0 0x0 0x50000000 0x01000000>, <1 0x0 0x51000000 0x01000000>; 52 + dma-ranges = <0 0x0 0x50000000 0x01000000>, <1 0x0 0x51000000 0x01000000>; 53 + ide@1,0 { 54 + compatible = "intel,ixp4xx-compact-flash"; 55 + reg = <1 0x00000000 0x1000>, <1 0x00040000 0x1000>; 56 + interrupt-parent = <&gpio0>; 57 + interrupts = <12 IRQ_TYPE_EDGE_RISING>; 58 + }; 59 + }; 60 + 61 + ...
+168
Documentation/devicetree/bindings/bus/intel,ixp4xx-expansion-bus-controller.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/bus/intel,ixp4xx-expansion-bus-controller.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Intel IXP4xx Expansion Bus Controller 8 + 9 + description: | 10 + The IXP4xx expansion bus controller handles access to devices on the 11 + memory-mapped expansion bus on the Intel IXP4xx family of system on chips, 12 + including IXP42x, IXP43x, IXP45x and IXP46x. 13 + 14 + maintainers: 15 + - Linus Walleij <linus.walleij@linaro.org> 16 + 17 + properties: 18 + $nodename: 19 + pattern: '^bus@[0-9a-f]+$' 20 + 21 + compatible: 22 + items: 23 + - enum: 24 + - intel,ixp42x-expansion-bus-controller 25 + - intel,ixp43x-expansion-bus-controller 26 + - intel,ixp45x-expansion-bus-controller 27 + - intel,ixp46x-expansion-bus-controller 28 + - const: syscon 29 + 30 + reg: 31 + description: Control registers for the expansion bus, these are not 32 + inside the memory range handled by the expansion bus. 33 + maxItems: 1 34 + 35 + native-endian: 36 + $ref: /schemas/types.yaml#/definitions/flag 37 + description: The IXP4xx has a peculiar MMIO access scheme, as it changes 38 + the access pattern for words (swizzling) on the bus depending on whether 39 + the SoC is running in big-endian or little-endian mode. Thus the 40 + registers must always be accessed using native endianness. 41 + 42 + "#address-cells": 43 + description: | 44 + The first cell is the chip select number. 45 + The second cell is the address offset within the bank. 46 + const: 2 47 + 48 + "#size-cells": 49 + const: 1 50 + 51 + ranges: true 52 + dma-ranges: true 53 + 54 + patternProperties: 55 + "^.*@[0-7],[0-9a-f]+$": 56 + description: Devices attached to chip selects are represented as 57 + subnodes. 58 + type: object 59 + 60 + properties: 61 + intel,ixp4xx-eb-t1: 62 + description: Address timing, extend address phase with n cycles. 63 + $ref: /schemas/types.yaml#/definitions/uint32 64 + maximum: 3 65 + 66 + intel,ixp4xx-eb-t2: 67 + description: Setup chip select timing, extend setup phase with n cycles. 68 + $ref: /schemas/types.yaml#/definitions/uint32 69 + maximum: 3 70 + 71 + intel,ixp4xx-eb-t3: 72 + description: Strobe timing, extend strobe phase with n cycles. 73 + $ref: /schemas/types.yaml#/definitions/uint32 74 + maximum: 15 75 + 76 + intel,ixp4xx-eb-t4: 77 + description: Hold timing, extend hold phase with n cycles. 78 + $ref: /schemas/types.yaml#/definitions/uint32 79 + maximum: 3 80 + 81 + intel,ixp4xx-eb-t5: 82 + description: Recovery timing, extend recovery phase with n cycles. 83 + $ref: /schemas/types.yaml#/definitions/uint32 84 + maximum: 15 85 + 86 + intel,ixp4xx-eb-cycle-type: 87 + description: The type of cycles to use on the expansion bus for this 88 + chip select. 0 = Intel cycles, 1 = Motorola cycles, 2 = HPI cycles. 89 + $ref: /schemas/types.yaml#/definitions/uint32 90 + enum: [0, 1, 2] 91 + 92 + intel,ixp4xx-eb-byte-access-on-halfword: 93 + description: Allow byte read access on half word devices. 94 + $ref: /schemas/types.yaml#/definitions/uint32 95 + enum: [0, 1] 96 + 97 + intel,ixp4xx-eb-hpi-hrdy-pol-high: 98 + description: Set HPI HRDY polarity to active high when using HPI. 99 + $ref: /schemas/types.yaml#/definitions/uint32 100 + enum: [0, 1] 101 + 102 + intel,ixp4xx-eb-mux-address-and-data: 103 + description: Multiplex address and data on the data bus. 104 + $ref: /schemas/types.yaml#/definitions/uint32 105 + enum: [0, 1] 106 + 107 + intel,ixp4xx-eb-ahb-split-transfers: 108 + description: Enable AHB split transfers. 109 + $ref: /schemas/types.yaml#/definitions/uint32 110 + enum: [0, 1] 111 + 112 + intel,ixp4xx-eb-write-enable: 113 + description: Enable write cycles. 114 + $ref: /schemas/types.yaml#/definitions/uint32 115 + enum: [0, 1] 116 + 117 + intel,ixp4xx-eb-byte-access: 118 + description: Expansion bus uses only 8 bits. The default is to use 119 + 16 bits. 120 + $ref: /schemas/types.yaml#/definitions/uint32 121 + enum: [0, 1] 122 + 123 + required: 124 + - compatible 125 + - reg 126 + - native-endian 127 + - "#address-cells" 128 + - "#size-cells" 129 + - ranges 130 + - dma-ranges 131 + 132 + additionalProperties: false 133 + 134 + examples: 135 + - | 136 + #include <dt-bindings/interrupt-controller/irq.h> 137 + bus@50000000 { 138 + compatible = "intel,ixp42x-expansion-bus-controller", "syscon"; 139 + reg = <0xc4000000 0x28>; 140 + native-endian; 141 + #address-cells = <2>; 142 + #size-cells = <1>; 143 + ranges = <0 0x0 0x50000000 0x01000000>, 144 + <1 0x0 0x51000000 0x01000000>; 145 + dma-ranges = <0 0x0 0x50000000 0x01000000>, 146 + <1 0x0 0x51000000 0x01000000>; 147 + flash@0,0 { 148 + compatible = "intel,ixp4xx-flash", "cfi-flash"; 149 + bank-width = <2>; 150 + reg = <0 0x00000000 0x1000000>; 151 + intel,ixp4xx-eb-t3 = <3>; 152 + intel,ixp4xx-eb-cycle-type = <0>; 153 + intel,ixp4xx-eb-byte-access-on-halfword = <1>; 154 + intel,ixp4xx-eb-write-enable = <1>; 155 + intel,ixp4xx-eb-byte-access = <0>; 156 + }; 157 + serial@1,0 { 158 + compatible = "exar,xr16l2551", "ns8250"; 159 + reg = <1 0x00000000 0x10>; 160 + interrupt-parent = <&gpio0>; 161 + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; 162 + clock-frequency = <1843200>; 163 + intel,ixp4xx-eb-t3 = <3>; 164 + intel,ixp4xx-eb-cycle-type = <1>; 165 + intel,ixp4xx-eb-write-enable = <1>; 166 + intel,ixp4xx-eb-byte-access = <1>; 167 + }; 168 + };
+2
MAINTAINERS
··· 2010 2010 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 2011 2011 S: Maintained 2012 2012 F: Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml 2013 + F: Documentation/devicetree/bindings/bus/intel,ixp4xx-expansion-bus-controller.yaml 2013 2014 F: Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt 2014 2015 F: Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml 2015 2016 F: Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml 2016 2017 F: arch/arm/mach-ixp4xx/ 2018 + F: drivers/bus/intel-ixp4xx-eb.c 2017 2019 F: drivers/clocksource/timer-ixp4xx.c 2018 2020 F: drivers/crypto/ixp4xx_crypto.c 2019 2021 F: drivers/gpio/gpio-ixp4xx.c
+183 -77
drivers/ata/pata_ixp4xx_cf.c
··· 13 13 */ 14 14 15 15 #include <linux/kernel.h> 16 + #include <linux/mfd/syscon.h> 16 17 #include <linux/module.h> 17 18 #include <linux/libata.h> 18 19 #include <linux/irq.h> 19 20 #include <linux/platform_device.h> 20 - #include <linux/platform_data/pata_ixp4xx_cf.h> 21 + #include <linux/regmap.h> 21 22 #include <scsi/scsi_host.h> 22 23 23 24 #define DRV_NAME "pata_ixp4xx_cf" 24 - #define DRV_VERSION "0.2" 25 + #define DRV_VERSION "1.0" 25 26 26 - static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error) 27 + struct ixp4xx_pata { 28 + struct ata_host *host; 29 + struct regmap *rmap; 30 + u32 cmd_csreg; 31 + void __iomem *cmd; 32 + void __iomem *ctl; 33 + }; 34 + 35 + #define IXP4XX_EXP_TIMING_STRIDE 0x04 36 + /* The timings for the chipselect is in bits 29..16 */ 37 + #define IXP4XX_EXP_T1_T5_MASK GENMASK(29, 16) 38 + #define IXP4XX_EXP_PIO_0_8 0x0a470000 39 + #define IXP4XX_EXP_PIO_1_8 0x06430000 40 + #define IXP4XX_EXP_PIO_2_8 0x02410000 41 + #define IXP4XX_EXP_PIO_3_8 0x00820000 42 + #define IXP4XX_EXP_PIO_4_8 0x00400000 43 + #define IXP4XX_EXP_PIO_0_16 0x29640000 44 + #define IXP4XX_EXP_PIO_1_16 0x05030000 45 + #define IXP4XX_EXP_PIO_2_16 0x00b20000 46 + #define IXP4XX_EXP_PIO_3_16 0x00820000 47 + #define IXP4XX_EXP_PIO_4_16 0x00400000 48 + #define IXP4XX_EXP_BW_MASK (BIT(6)|BIT(0)) 49 + #define IXP4XX_EXP_BYTE_RD16 BIT(6) /* Byte reads on half-word devices */ 50 + #define IXP4XX_EXP_BYTE_EN BIT(0) /* Use 8bit data bus if set */ 51 + 52 + static void ixp4xx_set_8bit_timing(struct ixp4xx_pata *ixpp, u8 pio_mode) 27 53 { 28 - struct ata_device *dev; 29 - 30 - ata_for_each_dev(dev, link, ENABLED) { 31 - ata_dev_info(dev, "configured for PIO0\n"); 32 - dev->pio_mode = XFER_PIO_0; 33 - dev->xfer_mode = XFER_PIO_0; 34 - dev->xfer_shift = ATA_SHIFT_PIO; 35 - dev->flags |= ATA_DFLAG_PIO; 54 + switch (pio_mode) { 55 + case XFER_PIO_0: 56 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 57 + IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_0_8); 58 + break; 59 + case XFER_PIO_1: 60 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 61 + IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_1_8); 62 + break; 63 + case XFER_PIO_2: 64 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 65 + IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_2_8); 66 + break; 67 + case XFER_PIO_3: 68 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 69 + IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_3_8); 70 + break; 71 + case XFER_PIO_4: 72 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 73 + IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_4_8); 74 + break; 75 + default: 76 + break; 36 77 } 37 - return 0; 78 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 79 + IXP4XX_EXP_BW_MASK, IXP4XX_EXP_BYTE_RD16|IXP4XX_EXP_BYTE_EN); 38 80 } 39 81 82 + static void ixp4xx_set_16bit_timing(struct ixp4xx_pata *ixpp, u8 pio_mode) 83 + { 84 + switch (pio_mode){ 85 + case XFER_PIO_0: 86 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 87 + IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_0_16); 88 + break; 89 + case XFER_PIO_1: 90 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 91 + IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_1_16); 92 + break; 93 + case XFER_PIO_2: 94 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 95 + IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_2_16); 96 + break; 97 + case XFER_PIO_3: 98 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 99 + IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_3_16); 100 + break; 101 + case XFER_PIO_4: 102 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 103 + IXP4XX_EXP_T1_T5_MASK, IXP4XX_EXP_PIO_4_16); 104 + break; 105 + default: 106 + break; 107 + } 108 + regmap_update_bits(ixpp->rmap, ixpp->cmd_csreg, 109 + IXP4XX_EXP_BW_MASK, IXP4XX_EXP_BYTE_RD16); 110 + } 111 + 112 + /* This sets up the timing on the chipselect CMD accordingly */ 113 + static void ixp4xx_set_piomode(struct ata_port *ap, struct ata_device *adev) 114 + { 115 + struct ixp4xx_pata *ixpp = ap->host->private_data; 116 + 117 + ata_dev_printk(adev, KERN_INFO, "configured for PIO%d 8bit\n", 118 + adev->pio_mode - XFER_PIO_0); 119 + ixp4xx_set_8bit_timing(ixpp, adev->pio_mode); 120 + } 121 + 122 + 40 123 static unsigned int ixp4xx_mmio_data_xfer(struct ata_queued_cmd *qc, 41 - unsigned char *buf, unsigned int buflen, int rw) 124 + unsigned char *buf, unsigned int buflen, int rw) 42 125 { 43 126 unsigned int i; 44 127 unsigned int words = buflen >> 1; 45 128 u16 *buf16 = (u16 *) buf; 129 + struct ata_device *adev = qc->dev; 46 130 struct ata_port *ap = qc->dev->link->ap; 47 131 void __iomem *mmio = ap->ioaddr.data_addr; 48 - struct ixp4xx_pata_data *data = dev_get_platdata(ap->host->dev); 132 + struct ixp4xx_pata *ixpp = ap->host->private_data; 133 + unsigned long flags; 134 + 135 + ata_dev_printk(adev, KERN_DEBUG, "%s %d bytes\n", (rw == READ) ? "READ" : "WRITE", 136 + buflen); 137 + spin_lock_irqsave(ap->lock, flags); 49 138 50 139 /* set the expansion bus in 16bit mode and restore 51 140 * 8 bit mode after the transaction. 52 141 */ 53 - *data->cs0_cfg &= ~(0x01); 54 - udelay(100); 142 + ixp4xx_set_16bit_timing(ixpp, adev->pio_mode); 143 + udelay(5); 55 144 56 145 /* Transfer multiple of 2 bytes */ 57 146 if (rw == READ) ··· 165 76 words++; 166 77 } 167 78 168 - udelay(100); 169 - *data->cs0_cfg |= 0x01; 79 + ixp4xx_set_8bit_timing(ixpp, adev->pio_mode); 80 + udelay(5); 81 + 82 + spin_unlock_irqrestore(ap->lock, flags); 170 83 171 84 return words << 1; 172 85 } ··· 181 90 .inherits = &ata_sff_port_ops, 182 91 .sff_data_xfer = ixp4xx_mmio_data_xfer, 183 92 .cable_detect = ata_cable_40wire, 184 - .set_mode = ixp4xx_set_mode, 93 + .set_piomode = ixp4xx_set_piomode, 94 + }; 95 + 96 + static struct ata_port_info ixp4xx_port_info = { 97 + .flags = ATA_FLAG_NO_ATAPI, 98 + .pio_mask = ATA_PIO4, 99 + .port_ops = &ixp4xx_port_ops, 185 100 }; 186 101 187 102 static void ixp4xx_setup_port(struct ata_port *ap, 188 - struct ixp4xx_pata_data *data, 189 - unsigned long raw_cs0, unsigned long raw_cs1) 103 + struct ixp4xx_pata *ixpp, 104 + unsigned long raw_cmd, unsigned long raw_ctl) 190 105 { 191 106 struct ata_ioports *ioaddr = &ap->ioaddr; 192 - unsigned long raw_cmd = raw_cs0; 193 - unsigned long raw_ctl = raw_cs1 + 0x06; 194 107 195 - ioaddr->cmd_addr = data->cs0; 196 - ioaddr->altstatus_addr = data->cs1 + 0x06; 197 - ioaddr->ctl_addr = data->cs1 + 0x06; 108 + raw_ctl += 0x06; 109 + ioaddr->cmd_addr = ixpp->cmd; 110 + ioaddr->altstatus_addr = ixpp->ctl + 0x06; 111 + ioaddr->ctl_addr = ixpp->ctl + 0x06; 198 112 199 113 ata_sff_std_ports(ioaddr); 200 114 201 - #ifndef __ARMEB__ 115 + if (!IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) { 116 + /* adjust the addresses to handle the address swizzling of the 117 + * ixp4xx in little endian mode. 118 + */ 202 119 203 - /* adjust the addresses to handle the address swizzling of the 204 - * ixp4xx in little endian mode. 205 - */ 120 + *(unsigned long *)&ioaddr->data_addr ^= 0x02; 121 + *(unsigned long *)&ioaddr->cmd_addr ^= 0x03; 122 + *(unsigned long *)&ioaddr->altstatus_addr ^= 0x03; 123 + *(unsigned long *)&ioaddr->ctl_addr ^= 0x03; 124 + *(unsigned long *)&ioaddr->error_addr ^= 0x03; 125 + *(unsigned long *)&ioaddr->feature_addr ^= 0x03; 126 + *(unsigned long *)&ioaddr->nsect_addr ^= 0x03; 127 + *(unsigned long *)&ioaddr->lbal_addr ^= 0x03; 128 + *(unsigned long *)&ioaddr->lbam_addr ^= 0x03; 129 + *(unsigned long *)&ioaddr->lbah_addr ^= 0x03; 130 + *(unsigned long *)&ioaddr->device_addr ^= 0x03; 131 + *(unsigned long *)&ioaddr->status_addr ^= 0x03; 132 + *(unsigned long *)&ioaddr->command_addr ^= 0x03; 206 133 207 - *(unsigned long *)&ioaddr->data_addr ^= 0x02; 208 - *(unsigned long *)&ioaddr->cmd_addr ^= 0x03; 209 - *(unsigned long *)&ioaddr->altstatus_addr ^= 0x03; 210 - *(unsigned long *)&ioaddr->ctl_addr ^= 0x03; 211 - *(unsigned long *)&ioaddr->error_addr ^= 0x03; 212 - *(unsigned long *)&ioaddr->feature_addr ^= 0x03; 213 - *(unsigned long *)&ioaddr->nsect_addr ^= 0x03; 214 - *(unsigned long *)&ioaddr->lbal_addr ^= 0x03; 215 - *(unsigned long *)&ioaddr->lbam_addr ^= 0x03; 216 - *(unsigned long *)&ioaddr->lbah_addr ^= 0x03; 217 - *(unsigned long *)&ioaddr->device_addr ^= 0x03; 218 - *(unsigned long *)&ioaddr->status_addr ^= 0x03; 219 - *(unsigned long *)&ioaddr->command_addr ^= 0x03; 220 - 221 - raw_cmd ^= 0x03; 222 - raw_ctl ^= 0x03; 223 - #endif 134 + raw_cmd ^= 0x03; 135 + raw_ctl ^= 0x03; 136 + } 224 137 225 138 ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", raw_cmd, raw_ctl); 226 139 } 227 140 228 141 static int ixp4xx_pata_probe(struct platform_device *pdev) 229 142 { 230 - struct resource *cs0, *cs1; 231 - struct ata_host *host; 232 - struct ata_port *ap; 233 - struct ixp4xx_pata_data *data = dev_get_platdata(&pdev->dev); 143 + struct resource *cmd, *ctl; 144 + struct ata_port_info pi = ixp4xx_port_info; 145 + const struct ata_port_info *ppi[] = { &pi, NULL }; 146 + struct device *dev = &pdev->dev; 147 + struct device_node *np = dev->of_node; 148 + struct ixp4xx_pata *ixpp; 149 + u32 csindex; 234 150 int ret; 235 151 int irq; 236 152 237 - cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); 238 - cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); 153 + cmd = platform_get_resource(pdev, IORESOURCE_MEM, 0); 154 + ctl = platform_get_resource(pdev, IORESOURCE_MEM, 1); 239 155 240 - if (!cs0 || !cs1) 156 + if (!cmd || !ctl) 241 157 return -EINVAL; 242 158 243 - /* allocate host */ 244 - host = ata_host_alloc(&pdev->dev, 1); 245 - if (!host) 159 + ixpp = devm_kzalloc(dev, sizeof(*ixpp), GFP_KERNEL); 160 + if (!ixpp) 246 161 return -ENOMEM; 247 162 248 - /* acquire resources and fill host */ 249 - ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); 163 + ixpp->rmap = syscon_node_to_regmap(np->parent); 164 + if (IS_ERR(ixpp->rmap)) 165 + return dev_err_probe(dev, PTR_ERR(ixpp->rmap), "no regmap\n"); 166 + /* Inspect our address to figure out what chipselect the CMD is on */ 167 + ret = of_property_read_u32_index(np, "reg", 0, &csindex); 168 + if (ret) 169 + return dev_err_probe(dev, ret, "can't inspect CMD address\n"); 170 + dev_info(dev, "using CS%d for PIO timing configuration\n", csindex); 171 + ixpp->cmd_csreg = csindex * IXP4XX_EXP_TIMING_STRIDE; 172 + 173 + ixpp->host = ata_host_alloc_pinfo(dev, ppi, 1); 174 + if (!ixpp->host) 175 + return -ENOMEM; 176 + ixpp->host->private_data = ixpp; 177 + 178 + ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); 250 179 if (ret) 251 180 return ret; 252 181 253 - data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000); 254 - data->cs1 = devm_ioremap(&pdev->dev, cs1->start, 0x1000); 255 - 256 - if (!data->cs0 || !data->cs1) 182 + ixpp->cmd = devm_ioremap_resource(dev, cmd); 183 + ixpp->ctl = devm_ioremap_resource(dev, ctl); 184 + if (IS_ERR(ixpp->cmd) || IS_ERR(ixpp->ctl)) 257 185 return -ENOMEM; 258 186 259 187 irq = platform_get_irq(pdev, 0); ··· 283 173 else 284 174 return -EINVAL; 285 175 286 - /* Setup expansion bus chip selects */ 287 - *data->cs0_cfg = data->cs0_bits; 288 - *data->cs1_cfg = data->cs1_bits; 176 + /* Just one port to set up */ 177 + ixp4xx_setup_port(ixpp->host->ports[0], ixpp, cmd->start, ctl->start); 289 178 290 - ap = host->ports[0]; 179 + ata_print_version_once(dev, DRV_VERSION); 291 180 292 - ap->ops = &ixp4xx_port_ops; 293 - ap->pio_mask = ATA_PIO4; 294 - ap->flags |= ATA_FLAG_NO_ATAPI; 295 - 296 - ixp4xx_setup_port(ap, data, cs0->start, cs1->start); 297 - 298 - ata_print_version_once(&pdev->dev, DRV_VERSION); 299 - 300 - /* activate host */ 301 - return ata_host_activate(host, irq, ata_sff_interrupt, 0, &ixp4xx_sht); 181 + return ata_host_activate(ixpp->host, irq, ata_sff_interrupt, 0, &ixp4xx_sht); 302 182 } 183 + 184 + static const struct of_device_id ixp4xx_pata_of_match[] = { 185 + { .compatible = "intel,ixp4xx-compact-flash", }, 186 + { }, 187 + }; 303 188 304 189 static struct platform_driver ixp4xx_pata_platform_driver = { 305 190 .driver = { 306 191 .name = DRV_NAME, 192 + .of_match_table = ixp4xx_pata_of_match, 307 193 }, 308 194 .probe = ixp4xx_pata_probe, 309 195 .remove = ata_platform_remove_one,
+11
drivers/bus/Kconfig
··· 95 95 The WEIM(Wireless External Interface Module) works like a bus. 96 96 You can attach many different devices on it, such as NOR, onenand. 97 97 98 + config INTEL_IXP4XX_EB 99 + bool "Intel IXP4xx expansion bus interface driver" 100 + depends on HAS_IOMEM 101 + depends on ARCH_IXP4XX || COMPILE_TEST 102 + default ARCH_IXP4XX 103 + select MFD_SYSCON 104 + help 105 + Driver for the Intel IXP4xx expansion bus interface. The driver is 106 + needed to set up various chip select configuration parameters before 107 + devices on the expansion bus can be discovered. 108 + 98 109 config MIPS_CDMM 99 110 bool "MIPS Common Device Memory Map (CDMM) Driver" 100 111 depends on CPU_MIPSR2 || CPU_MIPSR5
+1
drivers/bus/Makefile
··· 16 16 obj-$(CONFIG_BT1_APB) += bt1-apb.o 17 17 obj-$(CONFIG_BT1_AXI) += bt1-axi.o 18 18 obj-$(CONFIG_IMX_WEIM) += imx-weim.o 19 + obj-$(CONFIG_INTEL_IXP4XX_EB) += intel-ixp4xx-eb.o 19 20 obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o 20 21 obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o 21 22
+429
drivers/bus/intel-ixp4xx-eb.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Intel IXP4xx Expansion Bus Controller 4 + * Copyright (C) 2021 Linaro Ltd. 5 + * 6 + * Author: Linus Walleij <linus.walleij@linaro.org> 7 + */ 8 + 9 + #include <linux/bitfield.h> 10 + #include <linux/bits.h> 11 + #include <linux/err.h> 12 + #include <linux/init.h> 13 + #include <linux/log2.h> 14 + #include <linux/mfd/syscon.h> 15 + #include <linux/module.h> 16 + #include <linux/of.h> 17 + #include <linux/of_platform.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/regmap.h> 20 + 21 + #define IXP4XX_EXP_NUM_CS 8 22 + 23 + #define IXP4XX_EXP_TIMING_CS0 0x00 24 + #define IXP4XX_EXP_TIMING_CS1 0x04 25 + #define IXP4XX_EXP_TIMING_CS2 0x08 26 + #define IXP4XX_EXP_TIMING_CS3 0x0c 27 + #define IXP4XX_EXP_TIMING_CS4 0x10 28 + #define IXP4XX_EXP_TIMING_CS5 0x14 29 + #define IXP4XX_EXP_TIMING_CS6 0x18 30 + #define IXP4XX_EXP_TIMING_CS7 0x1c 31 + 32 + /* Bits inside each CS timing register */ 33 + #define IXP4XX_EXP_TIMING_STRIDE 0x04 34 + #define IXP4XX_EXP_CS_EN BIT(31) 35 + #define IXP456_EXP_PAR_EN BIT(30) /* Only on IXP45x and IXP46x */ 36 + #define IXP4XX_EXP_T1_MASK GENMASK(28, 27) 37 + #define IXP4XX_EXP_T1_SHIFT 28 38 + #define IXP4XX_EXP_T2_MASK GENMASK(27, 26) 39 + #define IXP4XX_EXP_T2_SHIFT 26 40 + #define IXP4XX_EXP_T3_MASK GENMASK(25, 22) 41 + #define IXP4XX_EXP_T3_SHIFT 22 42 + #define IXP4XX_EXP_T4_MASK GENMASK(21, 20) 43 + #define IXP4XX_EXP_T4_SHIFT 20 44 + #define IXP4XX_EXP_T5_MASK GENMASK(19, 16) 45 + #define IXP4XX_EXP_T5_SHIFT 16 46 + #define IXP4XX_EXP_CYC_TYPE_MASK GENMASK(15, 14) 47 + #define IXP4XX_EXP_CYC_TYPE_SHIFT 14 48 + #define IXP4XX_EXP_SIZE_MASK GENMASK(13, 10) 49 + #define IXP4XX_EXP_SIZE_SHIFT 10 50 + #define IXP4XX_EXP_CNFG_0 BIT(9) /* Always zero */ 51 + #define IXP43X_EXP_SYNC_INTEL BIT(8) /* Only on IXP43x */ 52 + #define IXP43X_EXP_EXP_CHIP BIT(7) /* Only on IXP43x */ 53 + #define IXP4XX_EXP_BYTE_RD16 BIT(6) 54 + #define IXP4XX_EXP_HRDY_POL BIT(5) /* Only on IXP42x */ 55 + #define IXP4XX_EXP_MUX_EN BIT(4) 56 + #define IXP4XX_EXP_SPLT_EN BIT(3) 57 + #define IXP4XX_EXP_WORD BIT(2) /* Always zero */ 58 + #define IXP4XX_EXP_WR_EN BIT(1) 59 + #define IXP4XX_EXP_BYTE_EN BIT(0) 60 + #define IXP42X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(8)|BIT(7)|IXP4XX_EXP_WORD) 61 + #define IXP43X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(5)|IXP4XX_EXP_WORD) 62 + 63 + #define IXP4XX_EXP_CNFG0 0x20 64 + #define IXP4XX_EXP_CNFG0_MEM_MAP BIT(31) 65 + #define IXP4XX_EXP_CNFG1 0x24 66 + 67 + #define IXP4XX_EXP_BOOT_BASE 0x00000000 68 + #define IXP4XX_EXP_NORMAL_BASE 0x50000000 69 + #define IXP4XX_EXP_STRIDE 0x01000000 70 + 71 + /* Fuses on the IXP43x */ 72 + #define IXP43X_EXP_UNIT_FUSE_RESET 0x28 73 + #define IXP43x_EXP_FUSE_SPEED_MASK GENMASK(23, 22) 74 + 75 + /* Number of device tree values in "reg" */ 76 + #define IXP4XX_OF_REG_SIZE 3 77 + 78 + struct ixp4xx_eb { 79 + struct device *dev; 80 + struct regmap *rmap; 81 + u32 bus_base; 82 + bool is_42x; 83 + bool is_43x; 84 + }; 85 + 86 + struct ixp4xx_exp_tim_prop { 87 + const char *prop; 88 + u32 max; 89 + u32 mask; 90 + u16 shift; 91 + }; 92 + 93 + static const struct ixp4xx_exp_tim_prop ixp4xx_exp_tim_props[] = { 94 + { 95 + .prop = "intel,ixp4xx-eb-t1", 96 + .max = 3, 97 + .mask = IXP4XX_EXP_T1_MASK, 98 + .shift = IXP4XX_EXP_T1_SHIFT, 99 + }, 100 + { 101 + .prop = "intel,ixp4xx-eb-t2", 102 + .max = 3, 103 + .mask = IXP4XX_EXP_T2_MASK, 104 + .shift = IXP4XX_EXP_T2_SHIFT, 105 + }, 106 + { 107 + .prop = "intel,ixp4xx-eb-t3", 108 + .max = 15, 109 + .mask = IXP4XX_EXP_T3_MASK, 110 + .shift = IXP4XX_EXP_T3_SHIFT, 111 + }, 112 + { 113 + .prop = "intel,ixp4xx-eb-t4", 114 + .max = 3, 115 + .mask = IXP4XX_EXP_T4_MASK, 116 + .shift = IXP4XX_EXP_T4_SHIFT, 117 + }, 118 + { 119 + .prop = "intel,ixp4xx-eb-t5", 120 + .max = 15, 121 + .mask = IXP4XX_EXP_T5_MASK, 122 + .shift = IXP4XX_EXP_T5_SHIFT, 123 + }, 124 + { 125 + .prop = "intel,ixp4xx-eb-byte-access-on-halfword", 126 + .max = 1, 127 + .mask = IXP4XX_EXP_BYTE_RD16, 128 + }, 129 + { 130 + .prop = "intel,ixp4xx-eb-hpi-hrdy-pol-high", 131 + .max = 1, 132 + .mask = IXP4XX_EXP_HRDY_POL, 133 + }, 134 + { 135 + .prop = "intel,ixp4xx-eb-mux-address-and-data", 136 + .max = 1, 137 + .mask = IXP4XX_EXP_MUX_EN, 138 + }, 139 + { 140 + .prop = "intel,ixp4xx-eb-ahb-split-transfers", 141 + .max = 1, 142 + .mask = IXP4XX_EXP_SPLT_EN, 143 + }, 144 + { 145 + .prop = "intel,ixp4xx-eb-write-enable", 146 + .max = 1, 147 + .mask = IXP4XX_EXP_WR_EN, 148 + }, 149 + { 150 + .prop = "intel,ixp4xx-eb-byte-access", 151 + .max = 1, 152 + .mask = IXP4XX_EXP_BYTE_EN, 153 + }, 154 + }; 155 + 156 + static void ixp4xx_exp_setup_chipselect(struct ixp4xx_eb *eb, 157 + struct device_node *np, 158 + u32 cs_index, 159 + u32 cs_size) 160 + { 161 + u32 cs_cfg; 162 + u32 val; 163 + u32 cur_cssize; 164 + u32 cs_order; 165 + int ret; 166 + int i; 167 + 168 + if (eb->is_42x && (cs_index > 7)) { 169 + dev_err(eb->dev, 170 + "invalid chipselect %u, we only support 0-7\n", 171 + cs_index); 172 + return; 173 + } 174 + if (eb->is_43x && (cs_index > 3)) { 175 + dev_err(eb->dev, 176 + "invalid chipselect %u, we only support 0-3\n", 177 + cs_index); 178 + return; 179 + } 180 + 181 + /* Several chip selects can be joined into one device */ 182 + if (cs_size > IXP4XX_EXP_STRIDE) 183 + cur_cssize = IXP4XX_EXP_STRIDE; 184 + else 185 + cur_cssize = cs_size; 186 + 187 + 188 + /* 189 + * The following will read/modify/write the configuration for one 190 + * chipselect, attempting to leave the boot defaults in place unless 191 + * something is explicitly defined. 192 + */ 193 + regmap_read(eb->rmap, IXP4XX_EXP_TIMING_CS0 + 194 + IXP4XX_EXP_TIMING_STRIDE * cs_index, &cs_cfg); 195 + dev_info(eb->dev, "CS%d at %#08x, size %#08x, config before: %#08x\n", 196 + cs_index, eb->bus_base + IXP4XX_EXP_STRIDE * cs_index, 197 + cur_cssize, cs_cfg); 198 + 199 + /* Size set-up first align to 2^9 .. 2^24 */ 200 + cur_cssize = roundup_pow_of_two(cur_cssize); 201 + if (cur_cssize < 512) 202 + cur_cssize = 512; 203 + cs_order = ilog2(cur_cssize); 204 + if (cs_order < 9 || cs_order > 24) { 205 + dev_err(eb->dev, "illegal size order %d\n", cs_order); 206 + return; 207 + } 208 + dev_dbg(eb->dev, "CS%d size order: %d\n", cs_index, cs_order); 209 + cs_cfg &= ~(IXP4XX_EXP_SIZE_MASK); 210 + cs_cfg |= ((cs_order - 9) << IXP4XX_EXP_SIZE_SHIFT); 211 + 212 + for (i = 0; i < ARRAY_SIZE(ixp4xx_exp_tim_props); i++) { 213 + const struct ixp4xx_exp_tim_prop *ip = &ixp4xx_exp_tim_props[i]; 214 + 215 + /* All are regular u32 values */ 216 + ret = of_property_read_u32(np, ip->prop, &val); 217 + if (ret) 218 + continue; 219 + 220 + /* Handle bools (single bits) first */ 221 + if (ip->max == 1) { 222 + if (val) 223 + cs_cfg |= ip->mask; 224 + else 225 + cs_cfg &= ~ip->mask; 226 + dev_info(eb->dev, "CS%d %s %s\n", cs_index, 227 + val ? "enabled" : "disabled", 228 + ip->prop); 229 + continue; 230 + } 231 + 232 + if (val > ip->max) { 233 + dev_err(eb->dev, 234 + "CS%d too high value for %s: %u, capped at %u\n", 235 + cs_index, ip->prop, val, ip->max); 236 + val = ip->max; 237 + } 238 + /* This assumes max value fills all the assigned bits (and it does) */ 239 + cs_cfg &= ~ip->mask; 240 + cs_cfg |= (val << ip->shift); 241 + dev_info(eb->dev, "CS%d set %s to %u\n", cs_index, ip->prop, val); 242 + } 243 + 244 + ret = of_property_read_u32(np, "intel,ixp4xx-eb-cycle-type", &val); 245 + if (!ret) { 246 + if (val > 3) { 247 + dev_err(eb->dev, "illegal cycle type %d\n", val); 248 + return; 249 + } 250 + dev_info(eb->dev, "CS%d set cycle type %d\n", cs_index, val); 251 + cs_cfg &= ~IXP4XX_EXP_CYC_TYPE_MASK; 252 + cs_cfg |= val << IXP4XX_EXP_CYC_TYPE_SHIFT; 253 + } 254 + 255 + if (eb->is_42x) 256 + cs_cfg &= ~IXP42X_RESERVED; 257 + if (eb->is_43x) { 258 + cs_cfg &= ~IXP43X_RESERVED; 259 + /* 260 + * This bit for Intel strata flash is currently unused, but let's 261 + * report it if we find one. 262 + */ 263 + if (cs_cfg & IXP43X_EXP_SYNC_INTEL) 264 + dev_info(eb->dev, "claims to be Intel strata flash\n"); 265 + } 266 + cs_cfg |= IXP4XX_EXP_CS_EN; 267 + 268 + regmap_write(eb->rmap, 269 + IXP4XX_EXP_TIMING_CS0 + IXP4XX_EXP_TIMING_STRIDE * cs_index, 270 + cs_cfg); 271 + dev_info(eb->dev, "CS%d wrote %#08x into CS config\n", cs_index, cs_cfg); 272 + 273 + /* 274 + * If several chip selects are joined together into one big 275 + * device area, we call ourselves recursively for each successive 276 + * chip select. For a 32MB flash chip this results in two calls 277 + * for example. 278 + */ 279 + if (cs_size > IXP4XX_EXP_STRIDE) 280 + ixp4xx_exp_setup_chipselect(eb, np, 281 + cs_index + 1, 282 + cs_size - IXP4XX_EXP_STRIDE); 283 + } 284 + 285 + static void ixp4xx_exp_setup_child(struct ixp4xx_eb *eb, 286 + struct device_node *np) 287 + { 288 + u32 cs_sizes[IXP4XX_EXP_NUM_CS]; 289 + int num_regs; 290 + u32 csindex; 291 + u32 cssize; 292 + int ret; 293 + int i; 294 + 295 + num_regs = of_property_count_elems_of_size(np, "reg", IXP4XX_OF_REG_SIZE); 296 + if (num_regs <= 0) 297 + return; 298 + dev_dbg(eb->dev, "child %s has %d register sets\n", 299 + of_node_full_name(np), num_regs); 300 + 301 + for (csindex = 0; csindex < IXP4XX_EXP_NUM_CS; csindex++) 302 + cs_sizes[csindex] = 0; 303 + 304 + for (i = 0; i < num_regs; i++) { 305 + u32 rbase, rsize; 306 + 307 + ret = of_property_read_u32_index(np, "reg", 308 + i * IXP4XX_OF_REG_SIZE, &csindex); 309 + if (ret) 310 + break; 311 + ret = of_property_read_u32_index(np, "reg", 312 + i * IXP4XX_OF_REG_SIZE + 1, &rbase); 313 + if (ret) 314 + break; 315 + ret = of_property_read_u32_index(np, "reg", 316 + i * IXP4XX_OF_REG_SIZE + 2, &rsize); 317 + if (ret) 318 + break; 319 + 320 + if (csindex >= IXP4XX_EXP_NUM_CS) { 321 + dev_err(eb->dev, "illegal CS %d\n", csindex); 322 + continue; 323 + } 324 + /* 325 + * The memory window always starts from CS base so we need to add 326 + * the start and size to get to the size from the start of the CS 327 + * base. For example if CS0 is at 0x50000000 and the reg is 328 + * <0 0xe40000 0x40000> the size is e80000. 329 + * 330 + * Roof this if we have several regs setting the same CS. 331 + */ 332 + cssize = rbase + rsize; 333 + dev_dbg(eb->dev, "CS%d size %#08x\n", csindex, cssize); 334 + if (cs_sizes[csindex] < cssize) 335 + cs_sizes[csindex] = cssize; 336 + } 337 + 338 + for (csindex = 0; csindex < IXP4XX_EXP_NUM_CS; csindex++) { 339 + cssize = cs_sizes[csindex]; 340 + if (!cssize) 341 + continue; 342 + /* Just this one, so set it up and return */ 343 + ixp4xx_exp_setup_chipselect(eb, np, csindex, cssize); 344 + } 345 + } 346 + 347 + static int ixp4xx_exp_probe(struct platform_device *pdev) 348 + { 349 + struct device *dev = &pdev->dev; 350 + struct device_node *np = dev->of_node; 351 + struct ixp4xx_eb *eb; 352 + struct device_node *child; 353 + bool have_children = false; 354 + u32 val; 355 + int ret; 356 + 357 + eb = devm_kzalloc(dev, sizeof(*eb), GFP_KERNEL); 358 + if (!eb) 359 + return -ENOMEM; 360 + 361 + eb->dev = dev; 362 + eb->is_42x = of_device_is_compatible(np, "intel,ixp42x-expansion-bus-controller"); 363 + eb->is_43x = of_device_is_compatible(np, "intel,ixp43x-expansion-bus-controller"); 364 + 365 + eb->rmap = syscon_node_to_regmap(np); 366 + if (IS_ERR(eb->rmap)) 367 + return dev_err_probe(dev, PTR_ERR(eb->rmap), "no regmap\n"); 368 + 369 + /* We check that the regmap work only on first read */ 370 + ret = regmap_read(eb->rmap, IXP4XX_EXP_CNFG0, &val); 371 + if (ret) 372 + dev_err_probe(dev, ret, "cannot read regmap\n"); 373 + if (val & IXP4XX_EXP_CNFG0_MEM_MAP) 374 + eb->bus_base = IXP4XX_EXP_BOOT_BASE; 375 + else 376 + eb->bus_base = IXP4XX_EXP_NORMAL_BASE; 377 + dev_info(dev, "expansion bus at %08x\n", eb->bus_base); 378 + 379 + if (eb->is_43x) { 380 + /* Check some fuses */ 381 + regmap_read(eb->rmap, IXP43X_EXP_UNIT_FUSE_RESET, &val); 382 + switch (FIELD_GET(IXP43x_EXP_FUSE_SPEED_MASK, val)) { 383 + case 0: 384 + dev_info(dev, "IXP43x at 533 MHz\n"); 385 + break; 386 + case 1: 387 + dev_info(dev, "IXP43x at 400 MHz\n"); 388 + break; 389 + case 2: 390 + dev_info(dev, "IXP43x at 667 MHz\n"); 391 + break; 392 + default: 393 + dev_info(dev, "IXP43x unknown speed\n"); 394 + break; 395 + } 396 + } 397 + 398 + /* Walk over the child nodes and see what chipselects we use */ 399 + for_each_available_child_of_node(np, child) { 400 + ixp4xx_exp_setup_child(eb, child); 401 + /* We have at least one child */ 402 + have_children = true; 403 + } 404 + 405 + if (have_children) 406 + return of_platform_default_populate(np, NULL, dev); 407 + 408 + return 0; 409 + } 410 + 411 + static const struct of_device_id ixp4xx_exp_of_match[] = { 412 + { .compatible = "intel,ixp42x-expansion-bus-controller", }, 413 + { .compatible = "intel,ixp43x-expansion-bus-controller", }, 414 + { .compatible = "intel,ixp45x-expansion-bus-controller", }, 415 + { .compatible = "intel,ixp46x-expansion-bus-controller", }, 416 + { } 417 + }; 418 + 419 + static struct platform_driver ixp4xx_exp_driver = { 420 + .probe = ixp4xx_exp_probe, 421 + .driver = { 422 + .name = "intel-extbus", 423 + .of_match_table = ixp4xx_exp_of_match, 424 + }, 425 + }; 426 + module_platform_driver(ixp4xx_exp_driver); 427 + MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 428 + MODULE_DESCRIPTION("Intel IXP4xx external bus driver"); 429 + MODULE_LICENSE("GPL");
+36 -12
drivers/clocksource/timer-ixp4xx.c
··· 18 18 #include <linux/delay.h> 19 19 #include <linux/of_address.h> 20 20 #include <linux/of_irq.h> 21 + #include <linux/platform_device.h> 21 22 /* Goes away with OF conversion */ 22 23 #include <linux/platform_data/timer-ixp4xx.h> 23 24 ··· 30 29 #define IXP4XX_OSRT1_OFFSET 0x08 /* Timer 1 Reload */ 31 30 #define IXP4XX_OST2_OFFSET 0x0C /* Timer 2 Timestamp */ 32 31 #define IXP4XX_OSRT2_OFFSET 0x10 /* Timer 2 Reload */ 33 - #define IXP4XX_OSWT_OFFSET 0x14 /* Watchdog Timer */ 34 - #define IXP4XX_OSWE_OFFSET 0x18 /* Watchdog Enable */ 35 - #define IXP4XX_OSWK_OFFSET 0x1C /* Watchdog Key */ 36 32 #define IXP4XX_OSST_OFFSET 0x20 /* Timer Status */ 37 33 38 34 /* ··· 43 45 #define IXP4XX_OSST_TIMER_1_PEND 0x00000001 44 46 #define IXP4XX_OSST_TIMER_2_PEND 0x00000002 45 47 #define IXP4XX_OSST_TIMER_TS_PEND 0x00000004 46 - #define IXP4XX_OSST_TIMER_WDOG_PEND 0x00000008 47 - #define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010 48 - 49 - #define IXP4XX_WDT_KEY 0x0000482E 50 - #define IXP4XX_WDT_RESET_ENABLE 0x00000001 51 - #define IXP4XX_WDT_IRQ_ENABLE 0x00000002 52 - #define IXP4XX_WDT_COUNT_ENABLE 0x00000004 48 + /* Remaining registers are for the watchdog and defined in the watchdog driver */ 53 49 54 50 struct ixp4xx_timer { 55 51 void __iomem *base; 56 - unsigned int tick_rate; 57 52 u32 latch; 58 53 struct clock_event_device clkevt; 59 54 #ifdef CONFIG_ARM ··· 172 181 if (!tmr) 173 182 return -ENOMEM; 174 183 tmr->base = base; 175 - tmr->tick_rate = timer_freq; 176 184 177 185 /* 178 186 * The timer register doesn't allow to specify the two least ··· 228 238 229 239 return 0; 230 240 } 241 + 242 + static struct platform_device ixp4xx_watchdog_device = { 243 + .name = "ixp4xx-watchdog", 244 + .id = -1, 245 + }; 246 + 247 + /* 248 + * This probe gets called after the timer is already up and running. The main 249 + * function on this platform is to spawn the watchdog device as a child. 250 + */ 251 + static int ixp4xx_timer_probe(struct platform_device *pdev) 252 + { 253 + struct device *dev = &pdev->dev; 254 + 255 + /* Pass the base address as platform data and nothing else */ 256 + ixp4xx_watchdog_device.dev.platform_data = local_ixp4xx_timer->base; 257 + ixp4xx_watchdog_device.dev.parent = dev; 258 + return platform_device_register(&ixp4xx_watchdog_device); 259 + } 260 + 261 + static const struct of_device_id ixp4xx_timer_dt_id[] = { 262 + { .compatible = "intel,ixp4xx-timer", }, 263 + { /* sentinel */ }, 264 + }; 265 + 266 + static struct platform_driver ixp4xx_timer_driver = { 267 + .probe = ixp4xx_timer_probe, 268 + .driver = { 269 + .name = "ixp4xx-timer", 270 + .of_match_table = ixp4xx_timer_dt_id, 271 + .suppress_bind_attrs = true, 272 + }, 273 + }; 274 + builtin_platform_driver(ixp4xx_timer_driver); 231 275 232 276 /** 233 277 * ixp4xx_timer_setup() - Timer setup function to be called from boardfiles
+1
drivers/watchdog/Kconfig
··· 487 487 config IXP4XX_WATCHDOG 488 488 tristate "IXP4xx Watchdog" 489 489 depends on ARCH_IXP4XX 490 + select WATCHDOG_CORE 490 491 help 491 492 Say Y here if to include support for the watchdog timer 492 493 in the Intel IXP4xx network processors. This driver can
+134 -181
drivers/watchdog/ixp4xx_wdt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * drivers/char/watchdog/ixp4xx_wdt.c 3 4 * 4 5 * Watchdog driver for Intel IXP4xx network processors 5 6 * 6 7 * Author: Deepak Saxena <dsaxena@plexity.net> 8 + * Author: Linus Walleij <linus.walleij@linaro.org> 7 9 * 8 10 * Copyright 2004 (c) MontaVista, Software, Inc. 9 11 * Based on sa1100 driver, Copyright (C) 2000 Oleg Drokin <green@crimea.edu> 10 - * 11 - * This file is licensed under the terms of the GNU General Public 12 - * License version 2. This program is licensed "as is" without any 13 - * warranty of any kind, whether express or implied. 14 12 */ 15 13 16 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 - 18 14 #include <linux/module.h> 19 - #include <linux/moduleparam.h> 20 15 #include <linux/types.h> 21 16 #include <linux/kernel.h> 22 - #include <linux/fs.h> 23 - #include <linux/miscdevice.h> 24 - #include <linux/of.h> 25 17 #include <linux/watchdog.h> 26 - #include <linux/init.h> 27 - #include <linux/bitops.h> 28 - #include <linux/uaccess.h> 29 - #include <mach/hardware.h> 18 + #include <linux/bits.h> 19 + #include <linux/platform_device.h> 20 + #include <linux/clk.h> 21 + #include <linux/soc/ixp4xx/cpu.h> 30 22 31 - static bool nowayout = WATCHDOG_NOWAYOUT; 32 - static int heartbeat = 60; /* (secs) Default is 1 minute */ 33 - static unsigned long wdt_status; 34 - static unsigned long boot_status; 35 - static DEFINE_SPINLOCK(wdt_lock); 36 - 37 - #define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL) 38 - 39 - #define WDT_IN_USE 0 40 - #define WDT_OK_TO_CLOSE 1 41 - 42 - static void wdt_enable(void) 43 - { 44 - spin_lock(&wdt_lock); 45 - *IXP4XX_OSWK = IXP4XX_WDT_KEY; 46 - *IXP4XX_OSWE = 0; 47 - *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat; 48 - *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE; 49 - *IXP4XX_OSWK = 0; 50 - spin_unlock(&wdt_lock); 51 - } 52 - 53 - static void wdt_disable(void) 54 - { 55 - spin_lock(&wdt_lock); 56 - *IXP4XX_OSWK = IXP4XX_WDT_KEY; 57 - *IXP4XX_OSWE = 0; 58 - *IXP4XX_OSWK = 0; 59 - spin_unlock(&wdt_lock); 60 - } 61 - 62 - static int ixp4xx_wdt_open(struct inode *inode, struct file *file) 63 - { 64 - if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 65 - return -EBUSY; 66 - 67 - clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 68 - wdt_enable(); 69 - return stream_open(inode, file); 70 - } 71 - 72 - static ssize_t 73 - ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 74 - { 75 - if (len) { 76 - if (!nowayout) { 77 - size_t i; 78 - 79 - clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 80 - 81 - for (i = 0; i != len; i++) { 82 - char c; 83 - 84 - if (get_user(c, data + i)) 85 - return -EFAULT; 86 - if (c == 'V') 87 - set_bit(WDT_OK_TO_CLOSE, &wdt_status); 88 - } 89 - } 90 - wdt_enable(); 91 - } 92 - return len; 93 - } 94 - 95 - static const struct watchdog_info ident = { 96 - .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | 97 - WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 98 - .identity = "IXP4xx Watchdog", 23 + struct ixp4xx_wdt { 24 + struct watchdog_device wdd; 25 + void __iomem *base; 26 + unsigned long rate; 99 27 }; 100 28 29 + /* Fallback if we do not have a clock for this */ 30 + #define IXP4XX_TIMER_FREQ 66666000 101 31 102 - static long ixp4xx_wdt_ioctl(struct file *file, unsigned int cmd, 103 - unsigned long arg) 32 + /* Registers after the timer registers */ 33 + #define IXP4XX_OSWT_OFFSET 0x14 /* Watchdog Timer */ 34 + #define IXP4XX_OSWE_OFFSET 0x18 /* Watchdog Enable */ 35 + #define IXP4XX_OSWK_OFFSET 0x1C /* Watchdog Key */ 36 + #define IXP4XX_OSST_OFFSET 0x20 /* Timer Status */ 37 + 38 + #define IXP4XX_OSST_TIMER_WDOG_PEND 0x00000008 39 + #define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010 40 + #define IXP4XX_WDT_KEY 0x0000482E 41 + #define IXP4XX_WDT_RESET_ENABLE 0x00000001 42 + #define IXP4XX_WDT_IRQ_ENABLE 0x00000002 43 + #define IXP4XX_WDT_COUNT_ENABLE 0x00000004 44 + 45 + static inline 46 + struct ixp4xx_wdt *to_ixp4xx_wdt(struct watchdog_device *wdd) 104 47 { 105 - int ret = -ENOTTY; 106 - int time; 107 - 108 - switch (cmd) { 109 - case WDIOC_GETSUPPORT: 110 - ret = copy_to_user((struct watchdog_info *)arg, &ident, 111 - sizeof(ident)) ? -EFAULT : 0; 112 - break; 113 - 114 - case WDIOC_GETSTATUS: 115 - ret = put_user(0, (int *)arg); 116 - break; 117 - 118 - case WDIOC_GETBOOTSTATUS: 119 - ret = put_user(boot_status, (int *)arg); 120 - break; 121 - 122 - case WDIOC_KEEPALIVE: 123 - wdt_enable(); 124 - ret = 0; 125 - break; 126 - 127 - case WDIOC_SETTIMEOUT: 128 - ret = get_user(time, (int *)arg); 129 - if (ret) 130 - break; 131 - 132 - if (time <= 0 || time > 60) { 133 - ret = -EINVAL; 134 - break; 135 - } 136 - 137 - heartbeat = time; 138 - wdt_enable(); 139 - fallthrough; 140 - 141 - case WDIOC_GETTIMEOUT: 142 - ret = put_user(heartbeat, (int *)arg); 143 - break; 144 - } 145 - return ret; 48 + return container_of(wdd, struct ixp4xx_wdt, wdd); 146 49 } 147 50 148 - static int ixp4xx_wdt_release(struct inode *inode, struct file *file) 51 + static int ixp4xx_wdt_start(struct watchdog_device *wdd) 149 52 { 150 - if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) 151 - wdt_disable(); 152 - else 153 - pr_crit("Device closed unexpectedly - timer will not stop\n"); 154 - clear_bit(WDT_IN_USE, &wdt_status); 155 - clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 53 + struct ixp4xx_wdt *iwdt = to_ixp4xx_wdt(wdd); 54 + 55 + __raw_writel(IXP4XX_WDT_KEY, iwdt->base + IXP4XX_OSWK_OFFSET); 56 + __raw_writel(0, iwdt->base + IXP4XX_OSWE_OFFSET); 57 + __raw_writel(wdd->timeout * iwdt->rate, 58 + iwdt->base + IXP4XX_OSWT_OFFSET); 59 + __raw_writel(IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE, 60 + iwdt->base + IXP4XX_OSWE_OFFSET); 61 + __raw_writel(0, iwdt->base + IXP4XX_OSWK_OFFSET); 156 62 157 63 return 0; 158 64 } 159 65 160 - 161 - static const struct file_operations ixp4xx_wdt_fops = { 162 - .owner = THIS_MODULE, 163 - .llseek = no_llseek, 164 - .write = ixp4xx_wdt_write, 165 - .unlocked_ioctl = ixp4xx_wdt_ioctl, 166 - .compat_ioctl = compat_ptr_ioctl, 167 - .open = ixp4xx_wdt_open, 168 - .release = ixp4xx_wdt_release, 169 - }; 170 - 171 - static struct miscdevice ixp4xx_wdt_miscdev = { 172 - .minor = WATCHDOG_MINOR, 173 - .name = "watchdog", 174 - .fops = &ixp4xx_wdt_fops, 175 - }; 176 - 177 - static int __init ixp4xx_wdt_init(void) 66 + static int ixp4xx_wdt_stop(struct watchdog_device *wdd) 178 67 { 68 + struct ixp4xx_wdt *iwdt = to_ixp4xx_wdt(wdd); 69 + 70 + __raw_writel(IXP4XX_WDT_KEY, iwdt->base + IXP4XX_OSWK_OFFSET); 71 + __raw_writel(0, iwdt->base + IXP4XX_OSWE_OFFSET); 72 + __raw_writel(0, iwdt->base + IXP4XX_OSWK_OFFSET); 73 + 74 + return 0; 75 + } 76 + 77 + static int ixp4xx_wdt_set_timeout(struct watchdog_device *wdd, 78 + unsigned int timeout) 79 + { 80 + wdd->timeout = timeout; 81 + if (watchdog_active(wdd)) 82 + ixp4xx_wdt_start(wdd); 83 + 84 + return 0; 85 + } 86 + 87 + static const struct watchdog_ops ixp4xx_wdt_ops = { 88 + .start = ixp4xx_wdt_start, 89 + .stop = ixp4xx_wdt_stop, 90 + .set_timeout = ixp4xx_wdt_set_timeout, 91 + .owner = THIS_MODULE, 92 + }; 93 + 94 + static const struct watchdog_info ixp4xx_wdt_info = { 95 + .options = WDIOF_KEEPALIVEPING 96 + | WDIOF_MAGICCLOSE 97 + | WDIOF_SETTIMEOUT, 98 + .identity = KBUILD_MODNAME, 99 + }; 100 + 101 + /* Devres-handled clock disablement */ 102 + static void ixp4xx_clock_action(void *d) 103 + { 104 + clk_disable_unprepare(d); 105 + } 106 + 107 + static int ixp4xx_wdt_probe(struct platform_device *pdev) 108 + { 109 + struct device *dev = &pdev->dev; 110 + struct ixp4xx_wdt *iwdt; 111 + struct clk *clk; 179 112 int ret; 180 113 181 - /* 182 - * FIXME: we bail out on device tree boot but this really needs 183 - * to be fixed in a nicer way: this registers the MDIO bus before 184 - * even matching the driver infrastructure, we should only probe 185 - * detected hardware. 186 - */ 187 - if (of_have_populated_dt()) 188 - return -ENODEV; 189 114 if (!(read_cpuid_id() & 0xf) && !cpu_is_ixp46x()) { 190 - pr_err("Rev. A0 IXP42x CPU detected - watchdog disabled\n"); 191 - 115 + dev_err(dev, "Rev. A0 IXP42x CPU detected - watchdog disabled\n"); 192 116 return -ENODEV; 193 117 } 194 - boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ? 195 - WDIOF_CARDRESET : 0; 196 - ret = misc_register(&ixp4xx_wdt_miscdev); 197 - if (ret == 0) 198 - pr_info("timer heartbeat %d sec\n", heartbeat); 199 - return ret; 118 + 119 + iwdt = devm_kzalloc(dev, sizeof(*iwdt), GFP_KERNEL); 120 + if (!iwdt) 121 + return -ENOMEM; 122 + iwdt->base = dev->platform_data; 123 + 124 + /* 125 + * Retrieve rate from a fixed clock from the device tree if 126 + * the parent has that, else use the default clock rate. 127 + */ 128 + clk = devm_clk_get(dev->parent, NULL); 129 + if (!IS_ERR(clk)) { 130 + ret = clk_prepare_enable(clk); 131 + if (ret) 132 + return ret; 133 + ret = devm_add_action_or_reset(dev, ixp4xx_clock_action, clk); 134 + if (ret) 135 + return ret; 136 + iwdt->rate = clk_get_rate(clk); 137 + } 138 + if (!iwdt->rate) 139 + iwdt->rate = IXP4XX_TIMER_FREQ; 140 + 141 + iwdt->wdd.info = &ixp4xx_wdt_info; 142 + iwdt->wdd.ops = &ixp4xx_wdt_ops; 143 + iwdt->wdd.min_timeout = 1; 144 + iwdt->wdd.max_timeout = U32_MAX / iwdt->rate; 145 + iwdt->wdd.parent = dev; 146 + /* Default to 60 seconds */ 147 + iwdt->wdd.timeout = 60U; 148 + watchdog_init_timeout(&iwdt->wdd, 0, dev); 149 + 150 + if (__raw_readl(iwdt->base + IXP4XX_OSST_OFFSET) & 151 + IXP4XX_OSST_TIMER_WARM_RESET) 152 + iwdt->wdd.bootstatus = WDIOF_CARDRESET; 153 + 154 + ret = devm_watchdog_register_device(dev, &iwdt->wdd); 155 + if (ret) 156 + return ret; 157 + 158 + dev_info(dev, "IXP4xx watchdog available\n"); 159 + 160 + return 0; 200 161 } 201 162 202 - static void __exit ixp4xx_wdt_exit(void) 203 - { 204 - misc_deregister(&ixp4xx_wdt_miscdev); 205 - } 206 - 207 - 208 - module_init(ixp4xx_wdt_init); 209 - module_exit(ixp4xx_wdt_exit); 163 + static struct platform_driver ixp4xx_wdt_driver = { 164 + .probe = ixp4xx_wdt_probe, 165 + .driver = { 166 + .name = "ixp4xx-watchdog", 167 + }, 168 + }; 169 + module_platform_driver(ixp4xx_wdt_driver); 210 170 211 171 MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); 212 172 MODULE_DESCRIPTION("IXP4xx Network Processor Watchdog"); 213 - 214 - module_param(heartbeat, int, 0); 215 - MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 60s)"); 216 - 217 - module_param(nowayout, bool, 0); 218 - MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); 219 - 220 173 MODULE_LICENSE("GPL");
+2 -2
include/linux/platform_data/pata_ixp4xx_cf.h
··· 14 14 volatile u32 *cs1_cfg; 15 15 unsigned long cs0_bits; 16 16 unsigned long cs1_bits; 17 - void __iomem *cs0; 18 - void __iomem *cs1; 17 + void __iomem *cmd; 18 + void __iomem *ctl; 19 19 }; 20 20 21 21 #endif