Memory controller drivers for v6.2, part two
1. ARM PL353: document PL354 in bindings. 2. TI/OMAP GPMC: allow setting wait-pin polarity. -----BEGIN PGP SIGNATURE----- iQJEBAABCgAuFiEE3dJiKD0RGyM7briowTdm5oaLg9cFAmN0rokQHGtyemtAa2Vy bmVsLm9yZwAKCRDBN2bmhouD15XSD/wJOuIEjIMwEs8M5i2PnXD4JGkG20tc22kj cD2RN9DRONeO4VQtDY73/DzZJ12JGRHIMU+UQkrvydef6WhGlKjyLPzFij1dSbVN PUmwM6jVMC0UjlEAaLnqfGYUZdhI1AAdZRowWTeDNhnTZ3G4MGpCe26shWXcZI0d cOkXAxcqmooh2wDmXAPzLcH49a5uOlmDKa3mwtqj5lpEKI/AQ1R8D4pqNIClPN8r oz7tDVGFnCo1MYZdY6k4o1K+Kut2M95phBbXB7Kl1+/tWg24loZGDUFPh/qBTXsF cpHAMwnmh+PPq5sRY8gtDqXA6WeawGpXYKBx9CRroRH5bUynqvNJkdWvKsIQyxpL w5waqwadMH+hoiXXI/ciqaX77geSzSCGfiQ0C66t823ubxC2gP/CS8y6K8FR7tLL srD0Kz4e1RaRV8e9Y+jgYkRV34ENmbztHTwMv/17wCjZs7MDDrQCV3fAmybnwDrW YHOvovnxETnfAFTK6M+cXBW5U0jbDzijGhr4CXDWlySBV4RClO4kga9fu2UNz9FM 0Hn6EjxaT71KAKirUzxP5lumMrI6QCUpUHLoqTNRP6Gd6Y1AkgEJh2gnqF8QiphZ yg+JUy2Y59rg1kBgxFZxTZwull4UNVzG9MQ2JPGfSoRuUV6LZxc2OlH3dDr+MU+R ldgXWDKXwg== =NZo/ -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmN7nsYACgkQmmx57+YA GNnsVRAAklSlSEtuLw2yumWvTE5trerQ5a1pFqy55WHKbySAlUU7I5J1/sER8FCy FW5V1IvDewUE94OgYqXQk4P6jrdN0h3MphK0MVfhxlfhlKO5TdZe+MGKR2gheK9+ o6k28PP3xtKuC0VY4Qv/HdnPQ9Hq//BDHNUCvx9l960OQv198QqFxM5lGPCxJcL2 JxIhRTuvZb37XgQgOtFMPLVPbApgSfWwoVwjkx+GFRe1Zuv9vjlEYPARlbJhSvXp FHmM+v7VxNQqSOwTB0yITtlXThHi28d8cM+FIxREBFlfkSVdUGjxVrEJjpFR7emV UOwdqxgmgpM5OjjkQwB2KHvulqHnq4pemQl9klaTY3Xwm7aKrFoaZf4XumNuo8gW kNJB89ODlMo/lutf0dB1MgSj6rSTqEoL3svqCmGhrPdjF0CH55l75QoyjIAq+67q A13YovG7nxngecE6qP4PFh3rBlUq51m5D0qLlA3diR5OaR77nsdXPLERSs3S9V8n s0FqFq3Hz/xZuUSXTweOQs9QF9BJZKv0VMb6flHpGHsB6+exmXBe4WXaJa5vv2iW o0u8AHtirposBPl5S/z7ecbzMEd4B0PRPzCHYAQ6t/vM6rbkZnYdynUb+QBH1+68 yo7N4y9mjuYwkaJRQOXXaXN3yY3GQt0iUHFULBPlhX84LqcvYCo= =HSYo -----END PGP SIGNATURE----- Merge tag 'memory-controller-drv-6.2-2' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl into soc/drivers Memory controller drivers for v6.2, part two 1. ARM PL353: document PL354 in bindings. 2. TI/OMAP GPMC: allow setting wait-pin polarity. * tag 'memory-controller-drv-6.2-2' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl: memory: omap-gpmc: fix coverity issue "Control flow issues" dt-bindings: memory-controllers: ti,gpmc: add wait-pin polarity memory: omap-gpmc: wait pin additions MAINTAINERS: arm,pl353-smc: correct dt-binding path dt-bindings: memory-controllers: arm,pl353-smc: Extend to support 'arm,pl354' SMC Link: https://lore.kernel.org/r/20221116093509.19657-1-krzysztof.kozlowski@linaro.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
fe04716e17
@ -1,26 +1,31 @@
|
|||||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
%YAML 1.2
|
%YAML 1.2
|
||||||
---
|
---
|
||||||
$id: http://devicetree.org/schemas/memory-controllers/arm,pl353-smc.yaml#
|
$id: http://devicetree.org/schemas/memory-controllers/arm,pl35x-smc.yaml#
|
||||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
title: ARM PL353 Static Memory Controller (SMC) device-tree bindings
|
title: Arm PL35x Series Static Memory Controller (SMC)
|
||||||
|
|
||||||
maintainers:
|
maintainers:
|
||||||
- Miquel Raynal <miquel.raynal@bootlin.com>
|
- Miquel Raynal <miquel.raynal@bootlin.com>
|
||||||
- Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
|
- Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
|
||||||
|
|
||||||
description:
|
description: |
|
||||||
The PL353 Static Memory Controller is a bus where you can connect two kinds
|
The PL35x Static Memory Controller is a bus where you can connect two kinds
|
||||||
of memory interfaces, which are NAND and memory mapped interfaces (such as
|
of memory interfaces, which are NAND and memory mapped interfaces (such as
|
||||||
SRAM or NOR).
|
SRAM or NOR) depending on the specific configuration.
|
||||||
|
|
||||||
|
The TRM is available here:
|
||||||
|
https://documentation-service.arm.com/static/5e8e2524fd977155116a58aa
|
||||||
|
|
||||||
# We need a select here so we don't match all nodes with 'arm,primecell'
|
# We need a select here so we don't match all nodes with 'arm,primecell'
|
||||||
select:
|
select:
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
contains:
|
contains:
|
||||||
const: arm,pl353-smc-r2p1
|
enum:
|
||||||
|
- arm,pl353-smc-r2p1
|
||||||
|
- arm,pl354
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
|
|
||||||
@ -30,7 +35,9 @@ properties:
|
|||||||
|
|
||||||
compatible:
|
compatible:
|
||||||
items:
|
items:
|
||||||
- const: arm,pl353-smc-r2p1
|
- enum:
|
||||||
|
- arm,pl353-smc-r2p1
|
||||||
|
- arm,pl354
|
||||||
- const: arm,primecell
|
- const: arm,primecell
|
||||||
|
|
||||||
"#address-cells":
|
"#address-cells":
|
||||||
@ -46,30 +53,25 @@ properties:
|
|||||||
The three chip select regions are defined in 'ranges'.
|
The three chip select regions are defined in 'ranges'.
|
||||||
|
|
||||||
clocks:
|
clocks:
|
||||||
items:
|
minItems: 1
|
||||||
- description: clock for the memory device bus
|
maxItems: 2
|
||||||
- description: main clock of the SMC
|
|
||||||
|
|
||||||
clock-names:
|
clock-names:
|
||||||
items:
|
minItems: 1
|
||||||
- const: memclk
|
maxItems: 2
|
||||||
- const: apb_pclk
|
|
||||||
|
|
||||||
ranges:
|
ranges:
|
||||||
minItems: 1
|
minItems: 1
|
||||||
description: |
|
maxItems: 8
|
||||||
Memory bus areas for interacting with the devices. Reflects
|
|
||||||
the memory layout with four integer values following:
|
|
||||||
<cs-number> 0 <offset> <size>
|
|
||||||
items:
|
|
||||||
- description: NAND bank 0
|
|
||||||
- description: NOR/SRAM bank 0
|
|
||||||
- description: NOR/SRAM bank 1
|
|
||||||
|
|
||||||
interrupts: true
|
interrupts:
|
||||||
|
minItems: 1
|
||||||
|
items:
|
||||||
|
- description: Combined or Memory interface 0 IRQ
|
||||||
|
- description: Memory interface 1 IRQ
|
||||||
|
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"@[0-3],[a-f0-9]+$":
|
"@[0-7],[a-f0-9]+$":
|
||||||
type: object
|
type: object
|
||||||
description: |
|
description: |
|
||||||
The child device node represents the controller connected to the SMC
|
The child device node represents the controller connected to the SMC
|
||||||
@ -87,7 +89,7 @@ patternProperties:
|
|||||||
- description: |
|
- description: |
|
||||||
Chip-select ID, as in the parent range property.
|
Chip-select ID, as in the parent range property.
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 2
|
maximum: 7
|
||||||
- description: |
|
- description: |
|
||||||
Offset of the memory region requested by the device.
|
Offset of the memory region requested by the device.
|
||||||
- description: |
|
- description: |
|
||||||
@ -102,12 +104,36 @@ required:
|
|||||||
- reg
|
- reg
|
||||||
- clock-names
|
- clock-names
|
||||||
- clocks
|
- clocks
|
||||||
- "#address-cells"
|
|
||||||
- "#size-cells"
|
|
||||||
- ranges
|
|
||||||
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
contains:
|
||||||
|
const: arm,pl354
|
||||||
|
then:
|
||||||
|
properties:
|
||||||
|
clocks:
|
||||||
|
# According to TRM, really should be 3 clocks
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
const: apb_pclk
|
||||||
|
|
||||||
|
else:
|
||||||
|
properties:
|
||||||
|
clocks:
|
||||||
|
items:
|
||||||
|
- description: clock for the memory device bus
|
||||||
|
- description: main clock of the SMC
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
items:
|
||||||
|
- const: memclk
|
||||||
|
- const: apb_pclk
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
smcc: memory-controller@e000e000 {
|
smcc: memory-controller@e000e000 {
|
@ -230,6 +230,13 @@ properties:
|
|||||||
Wait-pin used by client. Must be less than "gpmc,num-waitpins".
|
Wait-pin used by client. Must be less than "gpmc,num-waitpins".
|
||||||
$ref: /schemas/types.yaml#/definitions/uint32
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
|
||||||
|
ti,wait-pin-polarity:
|
||||||
|
description: |
|
||||||
|
Set the desired polarity for the selected wait pin.
|
||||||
|
0 for active low, 1 for active high.
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
enum: [0, 1]
|
||||||
|
|
||||||
gpmc,wait-on-read:
|
gpmc,wait-on-read:
|
||||||
description: Enables wait monitoring on reads.
|
description: Enables wait monitoring on reads.
|
||||||
type: boolean
|
type: boolean
|
||||||
|
@ -1685,7 +1685,7 @@ M: Miquel Raynal <miquel.raynal@bootlin.com>
|
|||||||
M: Naga Sureshkumar Relli <nagasure@xilinx.com>
|
M: Naga Sureshkumar Relli <nagasure@xilinx.com>
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/memory-controllers/arm,pl353-smc.yaml
|
F: Documentation/devicetree/bindings/memory-controllers/arm,pl35x-smc.yaml
|
||||||
F: drivers/memory/pl353-smc.c
|
F: drivers/memory/pl353-smc.c
|
||||||
|
|
||||||
ARM PRIMECELL CLCD PL110 DRIVER
|
ARM PRIMECELL CLCD PL110 DRIVER
|
||||||
|
@ -134,6 +134,7 @@
|
|||||||
#define GPMC_CONFIG_DEV_SIZE 0x00000002
|
#define GPMC_CONFIG_DEV_SIZE 0x00000002
|
||||||
#define GPMC_CONFIG_DEV_TYPE 0x00000003
|
#define GPMC_CONFIG_DEV_TYPE 0x00000003
|
||||||
|
|
||||||
|
#define GPMC_CONFIG_WAITPINPOLARITY(pin) (BIT(pin) << 8)
|
||||||
#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31)
|
#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31)
|
||||||
#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30)
|
#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30)
|
||||||
#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29)
|
#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29)
|
||||||
@ -229,6 +230,12 @@ struct omap3_gpmc_regs {
|
|||||||
struct gpmc_cs_config cs_context[GPMC_CS_NUM];
|
struct gpmc_cs_config cs_context[GPMC_CS_NUM];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct gpmc_waitpin {
|
||||||
|
u32 pin;
|
||||||
|
u32 polarity;
|
||||||
|
struct gpio_desc *desc;
|
||||||
|
};
|
||||||
|
|
||||||
struct gpmc_device {
|
struct gpmc_device {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int irq;
|
int irq;
|
||||||
@ -236,6 +243,7 @@ struct gpmc_device {
|
|||||||
struct gpio_chip gpio_chip;
|
struct gpio_chip gpio_chip;
|
||||||
struct notifier_block nb;
|
struct notifier_block nb;
|
||||||
struct omap3_gpmc_regs context;
|
struct omap3_gpmc_regs context;
|
||||||
|
struct gpmc_waitpin *waitpins;
|
||||||
int nirqs;
|
int nirqs;
|
||||||
unsigned int is_suspended:1;
|
unsigned int is_suspended:1;
|
||||||
struct resource *data;
|
struct resource *data;
|
||||||
@ -1035,6 +1043,62 @@ void gpmc_cs_free(int cs)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(gpmc_cs_free);
|
EXPORT_SYMBOL(gpmc_cs_free);
|
||||||
|
|
||||||
|
static bool gpmc_is_valid_waitpin(u32 waitpin)
|
||||||
|
{
|
||||||
|
return waitpin < gpmc_nr_waitpins;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gpmc_alloc_waitpin(struct gpmc_device *gpmc,
|
||||||
|
struct gpmc_settings *p)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct gpmc_waitpin *waitpin;
|
||||||
|
struct gpio_desc *waitpin_desc;
|
||||||
|
|
||||||
|
if (!gpmc_is_valid_waitpin(p->wait_pin))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
waitpin = &gpmc->waitpins[p->wait_pin];
|
||||||
|
|
||||||
|
if (!waitpin->desc) {
|
||||||
|
/* Reserve the GPIO for wait pin usage.
|
||||||
|
* GPIO polarity doesn't matter here. Wait pin polarity
|
||||||
|
* is set in GPMC_CONFIG register.
|
||||||
|
*/
|
||||||
|
waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip,
|
||||||
|
p->wait_pin, "WAITPIN",
|
||||||
|
GPIO_ACTIVE_HIGH,
|
||||||
|
GPIOD_IN);
|
||||||
|
|
||||||
|
ret = PTR_ERR(waitpin_desc);
|
||||||
|
if (IS_ERR(waitpin_desc) && ret != -EBUSY)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* New wait pin */
|
||||||
|
waitpin->desc = waitpin_desc;
|
||||||
|
waitpin->pin = p->wait_pin;
|
||||||
|
waitpin->polarity = p->wait_pin_polarity;
|
||||||
|
} else {
|
||||||
|
/* Shared wait pin */
|
||||||
|
if (p->wait_pin_polarity != waitpin->polarity ||
|
||||||
|
p->wait_pin != waitpin->pin) {
|
||||||
|
dev_err(gpmc->dev,
|
||||||
|
"shared-wait-pin: invalid configuration\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
dev_info(gpmc->dev, "shared wait-pin: %d\n", waitpin->pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gpmc_free_waitpin(struct gpmc_device *gpmc,
|
||||||
|
int wait_pin)
|
||||||
|
{
|
||||||
|
if (gpmc_is_valid_waitpin(wait_pin))
|
||||||
|
gpiochip_free_own_desc(gpmc->waitpins[wait_pin].desc);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gpmc_configure - write request to configure gpmc
|
* gpmc_configure - write request to configure gpmc
|
||||||
* @cmd: command type
|
* @cmd: command type
|
||||||
@ -1886,6 +1950,17 @@ int gpmc_cs_program_settings(int cs, struct gpmc_settings *p)
|
|||||||
|
|
||||||
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1);
|
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1);
|
||||||
|
|
||||||
|
if (p->wait_pin_polarity != GPMC_WAITPINPOLARITY_INVALID) {
|
||||||
|
config1 = gpmc_read_reg(GPMC_CONFIG);
|
||||||
|
|
||||||
|
if (p->wait_pin_polarity == GPMC_WAITPINPOLARITY_ACTIVE_LOW)
|
||||||
|
config1 &= ~GPMC_CONFIG_WAITPINPOLARITY(p->wait_pin);
|
||||||
|
else if (p->wait_pin_polarity == GPMC_WAITPINPOLARITY_ACTIVE_HIGH)
|
||||||
|
config1 |= GPMC_CONFIG_WAITPINPOLARITY(p->wait_pin);
|
||||||
|
|
||||||
|
gpmc_write_reg(GPMC_CONFIG, config1);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1975,7 +2050,25 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
|
|||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->wait_pin = GPMC_WAITPIN_INVALID;
|
||||||
|
p->wait_pin_polarity = GPMC_WAITPINPOLARITY_INVALID;
|
||||||
|
|
||||||
if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) {
|
if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) {
|
||||||
|
if (!gpmc_is_valid_waitpin(p->wait_pin)) {
|
||||||
|
pr_err("%s: Invalid wait-pin (%d)\n", __func__, p->wait_pin);
|
||||||
|
p->wait_pin = GPMC_WAITPIN_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!of_property_read_u32(np, "ti,wait-pin-polarity",
|
||||||
|
&p->wait_pin_polarity)) {
|
||||||
|
if (p->wait_pin_polarity != GPMC_WAITPINPOLARITY_ACTIVE_HIGH &&
|
||||||
|
p->wait_pin_polarity != GPMC_WAITPINPOLARITY_ACTIVE_LOW) {
|
||||||
|
pr_err("%s: Invalid wait-pin-polarity (%d)\n",
|
||||||
|
__func__, p->wait_pin_polarity);
|
||||||
|
p->wait_pin_polarity = GPMC_WAITPINPOLARITY_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p->wait_on_read = of_property_read_bool(np,
|
p->wait_on_read = of_property_read_bool(np,
|
||||||
"gpmc,wait-on-read");
|
"gpmc,wait-on-read");
|
||||||
p->wait_on_write = of_property_read_bool(np,
|
p->wait_on_write = of_property_read_bool(np,
|
||||||
@ -2080,7 +2173,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
|
|||||||
const char *name;
|
const char *name;
|
||||||
int ret, cs;
|
int ret, cs;
|
||||||
u32 val;
|
u32 val;
|
||||||
struct gpio_desc *waitpin_desc = NULL;
|
|
||||||
struct gpmc_device *gpmc = platform_get_drvdata(pdev);
|
struct gpmc_device *gpmc = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
if (of_property_read_u32(child, "reg", &cs) < 0) {
|
if (of_property_read_u32(child, "reg", &cs) < 0) {
|
||||||
@ -2208,17 +2300,9 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
|
|||||||
|
|
||||||
/* Reserve wait pin if it is required and valid */
|
/* Reserve wait pin if it is required and valid */
|
||||||
if (gpmc_s.wait_on_read || gpmc_s.wait_on_write) {
|
if (gpmc_s.wait_on_read || gpmc_s.wait_on_write) {
|
||||||
unsigned int wait_pin = gpmc_s.wait_pin;
|
ret = gpmc_alloc_waitpin(gpmc, &gpmc_s);
|
||||||
|
if (ret < 0)
|
||||||
waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip,
|
|
||||||
wait_pin, "WAITPIN",
|
|
||||||
GPIO_ACTIVE_HIGH,
|
|
||||||
GPIOD_IN);
|
|
||||||
if (IS_ERR(waitpin_desc)) {
|
|
||||||
dev_err(&pdev->dev, "invalid wait-pin: %d\n", wait_pin);
|
|
||||||
ret = PTR_ERR(waitpin_desc);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings");
|
gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings");
|
||||||
@ -2260,7 +2344,7 @@ err_child_fail:
|
|||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
|
|
||||||
err_cs:
|
err_cs:
|
||||||
gpiochip_free_own_desc(waitpin_desc);
|
gpmc_free_waitpin(gpmc, gpmc_s.wait_pin);
|
||||||
err:
|
err:
|
||||||
gpmc_cs_free(cs);
|
gpmc_cs_free(cs);
|
||||||
|
|
||||||
@ -2489,7 +2573,7 @@ static int omap_gpmc_context_notifier(struct notifier_block *nb,
|
|||||||
|
|
||||||
static int gpmc_probe(struct platform_device *pdev)
|
static int gpmc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc, i;
|
||||||
u32 l;
|
u32 l;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct gpmc_device *gpmc;
|
struct gpmc_device *gpmc;
|
||||||
@ -2545,6 +2629,15 @@ static int gpmc_probe(struct platform_device *pdev)
|
|||||||
gpmc_nr_waitpins = GPMC_NR_WAITPINS;
|
gpmc_nr_waitpins = GPMC_NR_WAITPINS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpmc->waitpins = devm_kzalloc(&pdev->dev,
|
||||||
|
gpmc_nr_waitpins * sizeof(struct gpmc_waitpin),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!gpmc->waitpins)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (i = 0; i < gpmc_nr_waitpins; i++)
|
||||||
|
gpmc->waitpins[i].pin = GPMC_WAITPIN_INVALID;
|
||||||
|
|
||||||
pm_runtime_enable(&pdev->dev);
|
pm_runtime_enable(&pdev->dev);
|
||||||
pm_runtime_get_sync(&pdev->dev);
|
pm_runtime_get_sync(&pdev->dev);
|
||||||
|
|
||||||
@ -2598,9 +2691,12 @@ gpio_init_failed:
|
|||||||
|
|
||||||
static int gpmc_remove(struct platform_device *pdev)
|
static int gpmc_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
struct gpmc_device *gpmc = platform_get_drvdata(pdev);
|
struct gpmc_device *gpmc = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
cpu_pm_unregister_notifier(&gpmc->nb);
|
cpu_pm_unregister_notifier(&gpmc->nb);
|
||||||
|
for (i = 0; i < gpmc_nr_waitpins; i++)
|
||||||
|
gpmc_free_waitpin(gpmc, i);
|
||||||
gpmc_free_irq(gpmc);
|
gpmc_free_irq(gpmc);
|
||||||
gpmc_mem_exit();
|
gpmc_mem_exit();
|
||||||
pm_runtime_put_sync(&pdev->dev);
|
pm_runtime_put_sync(&pdev->dev);
|
||||||
|
@ -136,6 +136,13 @@ struct gpmc_device_timings {
|
|||||||
#define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */
|
#define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */
|
||||||
#define GPMC_MUX_AD 2 /* Addr-Data multiplex */
|
#define GPMC_MUX_AD 2 /* Addr-Data multiplex */
|
||||||
|
|
||||||
|
/* Wait pin polarity values */
|
||||||
|
#define GPMC_WAITPINPOLARITY_INVALID UINT_MAX
|
||||||
|
#define GPMC_WAITPINPOLARITY_ACTIVE_LOW 0
|
||||||
|
#define GPMC_WAITPINPOLARITY_ACTIVE_HIGH 1
|
||||||
|
|
||||||
|
#define GPMC_WAITPIN_INVALID UINT_MAX
|
||||||
|
|
||||||
struct gpmc_settings {
|
struct gpmc_settings {
|
||||||
bool burst_wrap; /* enables wrap bursting */
|
bool burst_wrap; /* enables wrap bursting */
|
||||||
bool burst_read; /* enables read page/burst mode */
|
bool burst_read; /* enables read page/burst mode */
|
||||||
@ -149,6 +156,7 @@ struct gpmc_settings {
|
|||||||
u32 device_width; /* device bus width (8 or 16 bit) */
|
u32 device_width; /* device bus width (8 or 16 bit) */
|
||||||
u32 mux_add_data; /* multiplex address & data */
|
u32 mux_add_data; /* multiplex address & data */
|
||||||
u32 wait_pin; /* wait-pin to be used */
|
u32 wait_pin; /* wait-pin to be used */
|
||||||
|
u32 wait_pin_polarity;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Data for each chip select */
|
/* Data for each chip select */
|
||||||
|
Loading…
Reference in New Issue
Block a user