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

memory: omap-gpmc: wait pin additions

This patch introduces support for setting the wait-pin polarity as well
as using the same wait-pin for different CS regions.

The waitpin polarity can be configured via the WAITPIN<X>POLARITY bits
in the GPMC_CONFIG register. This is currently not supported by the
driver. This patch adds support for setting the required register bits
with the "ti,wait-pin-polarity" dt-property.

The wait-pin can also be shared between different CS regions for special
usecases. Therefore GPMC must keep track of wait-pin allocations, so it
knows that either GPMC itself or another driver has the ownership.

Signed-off-by: Benedikt Niedermayr <benedikt.niedermayr@siemens.com>
Link: https://lore.kernel.org/r/20221102133047.1654449-2-benedikt.niedermayr@siemens.com
Reviewed-by: Roger Quadros <rogerq@kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

authored by

Benedikt Niedermayr and committed by
Krzysztof Kozlowski
89aed3cd 3821e96a

+117 -13
+109 -13
drivers/memory/omap-gpmc.c
··· 134 134 #define GPMC_CONFIG_DEV_SIZE 0x00000002 135 135 #define GPMC_CONFIG_DEV_TYPE 0x00000003 136 136 137 + #define GPMC_CONFIG_WAITPINPOLARITY(pin) (BIT(pin) << 8) 137 138 #define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31) 138 139 #define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30) 139 140 #define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29) ··· 230 229 struct gpmc_cs_config cs_context[GPMC_CS_NUM]; 231 230 }; 232 231 232 + struct gpmc_waitpin { 233 + u32 pin; 234 + u32 polarity; 235 + struct gpio_desc *desc; 236 + }; 237 + 233 238 struct gpmc_device { 234 239 struct device *dev; 235 240 int irq; ··· 243 236 struct gpio_chip gpio_chip; 244 237 struct notifier_block nb; 245 238 struct omap3_gpmc_regs context; 239 + struct gpmc_waitpin *waitpins; 246 240 int nirqs; 247 241 unsigned int is_suspended:1; 248 242 struct resource *data; ··· 1042 1034 spin_unlock(&gpmc_mem_lock); 1043 1035 } 1044 1036 EXPORT_SYMBOL(gpmc_cs_free); 1037 + 1038 + static bool gpmc_is_valid_waitpin(u32 waitpin) 1039 + { 1040 + return waitpin >= 0 && waitpin < gpmc_nr_waitpins; 1041 + } 1042 + 1043 + static int gpmc_alloc_waitpin(struct gpmc_device *gpmc, 1044 + struct gpmc_settings *p) 1045 + { 1046 + int ret; 1047 + struct gpmc_waitpin *waitpin; 1048 + struct gpio_desc *waitpin_desc; 1049 + 1050 + if (!gpmc_is_valid_waitpin(p->wait_pin)) 1051 + return -EINVAL; 1052 + 1053 + waitpin = &gpmc->waitpins[p->wait_pin]; 1054 + 1055 + if (!waitpin->desc) { 1056 + /* Reserve the GPIO for wait pin usage. 1057 + * GPIO polarity doesn't matter here. Wait pin polarity 1058 + * is set in GPMC_CONFIG register. 1059 + */ 1060 + waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip, 1061 + p->wait_pin, "WAITPIN", 1062 + GPIO_ACTIVE_HIGH, 1063 + GPIOD_IN); 1064 + 1065 + ret = PTR_ERR(waitpin_desc); 1066 + if (IS_ERR(waitpin_desc) && ret != -EBUSY) 1067 + return ret; 1068 + 1069 + /* New wait pin */ 1070 + waitpin->desc = waitpin_desc; 1071 + waitpin->pin = p->wait_pin; 1072 + waitpin->polarity = p->wait_pin_polarity; 1073 + } else { 1074 + /* Shared wait pin */ 1075 + if (p->wait_pin_polarity != waitpin->polarity || 1076 + p->wait_pin != waitpin->pin) { 1077 + dev_err(gpmc->dev, 1078 + "shared-wait-pin: invalid configuration\n"); 1079 + return -EINVAL; 1080 + } 1081 + dev_info(gpmc->dev, "shared wait-pin: %d\n", waitpin->pin); 1082 + } 1083 + 1084 + return 0; 1085 + } 1086 + 1087 + static void gpmc_free_waitpin(struct gpmc_device *gpmc, 1088 + int wait_pin) 1089 + { 1090 + if (gpmc_is_valid_waitpin(wait_pin)) 1091 + gpiochip_free_own_desc(gpmc->waitpins[wait_pin].desc); 1092 + } 1045 1093 1046 1094 /** 1047 1095 * gpmc_configure - write request to configure gpmc ··· 1950 1886 1951 1887 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1); 1952 1888 1889 + if (p->wait_pin_polarity != GPMC_WAITPINPOLARITY_INVALID) { 1890 + config1 = gpmc_read_reg(GPMC_CONFIG); 1891 + 1892 + if (p->wait_pin_polarity == GPMC_WAITPINPOLARITY_ACTIVE_LOW) 1893 + config1 &= ~GPMC_CONFIG_WAITPINPOLARITY(p->wait_pin); 1894 + else if (p->wait_pin_polarity == GPMC_WAITPINPOLARITY_ACTIVE_HIGH) 1895 + config1 |= GPMC_CONFIG_WAITPINPOLARITY(p->wait_pin); 1896 + 1897 + gpmc_write_reg(GPMC_CONFIG, config1); 1898 + } 1899 + 1953 1900 return 0; 1954 1901 } 1955 1902 ··· 2050 1975 __func__); 2051 1976 } 2052 1977 1978 + p->wait_pin = GPMC_WAITPIN_INVALID; 1979 + p->wait_pin_polarity = GPMC_WAITPINPOLARITY_INVALID; 1980 + 2053 1981 if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) { 1982 + if (!gpmc_is_valid_waitpin(p->wait_pin)) { 1983 + pr_err("%s: Invalid wait-pin (%d)\n", __func__, p->wait_pin); 1984 + p->wait_pin = GPMC_WAITPIN_INVALID; 1985 + } 1986 + 1987 + if (!of_property_read_u32(np, "ti,wait-pin-polarity", 1988 + &p->wait_pin_polarity)) { 1989 + if (p->wait_pin_polarity != GPMC_WAITPINPOLARITY_ACTIVE_HIGH && 1990 + p->wait_pin_polarity != GPMC_WAITPINPOLARITY_ACTIVE_LOW) { 1991 + pr_err("%s: Invalid wait-pin-polarity (%d)\n", 1992 + __func__, p->wait_pin_polarity); 1993 + p->wait_pin_polarity = GPMC_WAITPINPOLARITY_INVALID; 1994 + } 1995 + } 1996 + 2054 1997 p->wait_on_read = of_property_read_bool(np, 2055 1998 "gpmc,wait-on-read"); 2056 1999 p->wait_on_write = of_property_read_bool(np, ··· 2173 2080 const char *name; 2174 2081 int ret, cs; 2175 2082 u32 val; 2176 - struct gpio_desc *waitpin_desc = NULL; 2177 2083 struct gpmc_device *gpmc = platform_get_drvdata(pdev); 2178 2084 2179 2085 if (of_property_read_u32(child, "reg", &cs) < 0) { ··· 2300 2208 2301 2209 /* Reserve wait pin if it is required and valid */ 2302 2210 if (gpmc_s.wait_on_read || gpmc_s.wait_on_write) { 2303 - unsigned int wait_pin = gpmc_s.wait_pin; 2304 - 2305 - waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip, 2306 - wait_pin, "WAITPIN", 2307 - GPIO_ACTIVE_HIGH, 2308 - GPIOD_IN); 2309 - if (IS_ERR(waitpin_desc)) { 2310 - dev_err(&pdev->dev, "invalid wait-pin: %d\n", wait_pin); 2311 - ret = PTR_ERR(waitpin_desc); 2211 + ret = gpmc_alloc_waitpin(gpmc, &gpmc_s); 2212 + if (ret < 0) 2312 2213 goto err; 2313 - } 2314 2214 } 2315 2215 2316 2216 gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings"); ··· 2344 2260 ret = -ENODEV; 2345 2261 2346 2262 err_cs: 2347 - gpiochip_free_own_desc(waitpin_desc); 2263 + gpmc_free_waitpin(gpmc, gpmc_s.wait_pin); 2348 2264 err: 2349 2265 gpmc_cs_free(cs); 2350 2266 ··· 2573 2489 2574 2490 static int gpmc_probe(struct platform_device *pdev) 2575 2491 { 2576 - int rc; 2492 + int rc, i; 2577 2493 u32 l; 2578 2494 struct resource *res; 2579 2495 struct gpmc_device *gpmc; ··· 2629 2545 gpmc_nr_waitpins = GPMC_NR_WAITPINS; 2630 2546 } 2631 2547 2548 + gpmc->waitpins = devm_kzalloc(&pdev->dev, 2549 + gpmc_nr_waitpins * sizeof(struct gpmc_waitpin), 2550 + GFP_KERNEL); 2551 + if (!gpmc->waitpins) 2552 + return -ENOMEM; 2553 + 2554 + for (i = 0; i < gpmc_nr_waitpins; i++) 2555 + gpmc->waitpins[i].pin = GPMC_WAITPIN_INVALID; 2556 + 2632 2557 pm_runtime_enable(&pdev->dev); 2633 2558 pm_runtime_get_sync(&pdev->dev); 2634 2559 ··· 2691 2598 2692 2599 static int gpmc_remove(struct platform_device *pdev) 2693 2600 { 2601 + int i; 2694 2602 struct gpmc_device *gpmc = platform_get_drvdata(pdev); 2695 2603 2696 2604 cpu_pm_unregister_notifier(&gpmc->nb); 2605 + for (i = 0; i < gpmc_nr_waitpins; i++) 2606 + gpmc_free_waitpin(gpmc, i); 2697 2607 gpmc_free_irq(gpmc); 2698 2608 gpmc_mem_exit(); 2699 2609 pm_runtime_put_sync(&pdev->dev);
+8
include/linux/platform_data/gpmc-omap.h
··· 136 136 #define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */ 137 137 #define GPMC_MUX_AD 2 /* Addr-Data multiplex */ 138 138 139 + /* Wait pin polarity values */ 140 + #define GPMC_WAITPINPOLARITY_INVALID -1 141 + #define GPMC_WAITPINPOLARITY_ACTIVE_LOW 0 142 + #define GPMC_WAITPINPOLARITY_ACTIVE_HIGH 1 143 + 144 + #define GPMC_WAITPIN_INVALID -1 145 + 139 146 struct gpmc_settings { 140 147 bool burst_wrap; /* enables wrap bursting */ 141 148 bool burst_read; /* enables read page/burst mode */ ··· 156 149 u32 device_width; /* device bus width (8 or 16 bit) */ 157 150 u32 mux_add_data; /* multiplex address & data */ 158 151 u32 wait_pin; /* wait-pin to be used */ 152 + u32 wait_pin_polarity; 159 153 }; 160 154 161 155 /* Data for each chip select */