aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2016-03-07 05:18:43 -0500
committerRoger Quadros <rogerq@ti.com>2016-04-15 04:54:12 -0400
commitd2d00862dfbbd22d80ee67f816cb7eeaea71f03b (patch)
tree163ba53823447c5231c372acb6b3be640b2cf453
parent3c76f6119a64eb8ff6d088ceb6ca03891e29a7ce (diff)
memory: omap-gpmc: Support general purpose input for WAITPINs
OMAPs can have 2 to 4 WAITPINs that can be used as general purpose input if not used for memory wait state insertion. The first user will be the OMAP NAND chip to get the NAND read/busy status using gpiolib. Signed-off-by: Roger Quadros <rogerq@ti.com> Acked-by: Rob Herring <robh@kernel.org> Acked-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt6
-rw-r--r--drivers/memory/Kconfig1
-rw-r--r--drivers/memory/omap-gpmc.c117
3 files changed, 112 insertions, 12 deletions
diff --git a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt b/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
index 13f13786f992..97e71924dbbb 100644
--- a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
@@ -38,6 +38,10 @@ Required properties:
38 0 - NAND_fifoevent 38 0 - NAND_fifoevent
39 1 - NAND_termcount 39 1 - NAND_termcount
40 - interrupt-cells: Must be set to 2 40 - interrupt-cells: Must be set to 2
41 - gpio-controller: The GPMC driver implements a GPIO controller for the
42 GPMC WAIT pins that can be used as general purpose inputs.
43 0 maps to GPMC_WAIT0 pin.
44 - gpio-cells: Must be set to 2
41 45
42Timing properties for child nodes. All are optional and default to 0. 46Timing properties for child nodes. All are optional and default to 0.
43 47
@@ -138,6 +142,8 @@ Example for an AM33xx board:
138 ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */ 142 ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
139 interrupt-controller; 143 interrupt-controller;
140 #interrupt-cells = <2>; 144 #interrupt-cells = <2>;
145 gpio-controller;
146 #gpio-cells = <2>;
141 147
142 /* child nodes go here */ 148 /* child nodes go here */
143 }; 149 };
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 51d5cd20c26a..a9b1c1419bef 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -51,6 +51,7 @@ config TI_EMIF
51 51
52config OMAP_GPMC 52config OMAP_GPMC
53 bool 53 bool
54 select GPIOLIB
54 help 55 help
55 This driver is for the General Purpose Memory Controller (GPMC) 56 This driver is for the General Purpose Memory Controller (GPMC)
56 present on Texas Instruments SoCs (e.g. OMAP2+). GPMC allows 57 present on Texas Instruments SoCs (e.g. OMAP2+). GPMC allows
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index bfe4e8710973..4dd1c65ee70c 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -21,6 +21,7 @@
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/gpio/driver.h>
24#include <linux/interrupt.h> 25#include <linux/interrupt.h>
25#include <linux/irqdomain.h> 26#include <linux/irqdomain.h>
26#include <linux/platform_device.h> 27#include <linux/platform_device.h>
@@ -237,6 +238,7 @@ struct gpmc_device {
237 struct device *dev; 238 struct device *dev;
238 int irq; 239 int irq;
239 struct irq_chip irq_chip; 240 struct irq_chip irq_chip;
241 struct gpio_chip gpio_chip;
240}; 242};
241 243
242static struct irq_domain *gpmc_irq_domain; 244static struct irq_domain *gpmc_irq_domain;
@@ -2064,10 +2066,71 @@ err:
2064 return ret; 2066 return ret;
2065} 2067}
2066 2068
2069static int gpmc_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
2070{
2071 return 1; /* we're input only */
2072}
2073
2074static int gpmc_gpio_direction_input(struct gpio_chip *chip,
2075 unsigned int offset)
2076{
2077 return 0; /* we're input only */
2078}
2079
2080static int gpmc_gpio_direction_output(struct gpio_chip *chip,
2081 unsigned int offset, int value)
2082{
2083 return -EINVAL; /* we're input only */
2084}
2085
2086static void gpmc_gpio_set(struct gpio_chip *chip, unsigned int offset,
2087 int value)
2088{
2089}
2090
2091static int gpmc_gpio_get(struct gpio_chip *chip, unsigned int offset)
2092{
2093 u32 reg;
2094
2095 offset += 8;
2096
2097 reg = gpmc_read_reg(GPMC_STATUS) & BIT(offset);
2098
2099 return !!reg;
2100}
2101
2102static int gpmc_gpio_init(struct gpmc_device *gpmc)
2103{
2104 int ret;
2105
2106 gpmc->gpio_chip.parent = gpmc->dev;
2107 gpmc->gpio_chip.owner = THIS_MODULE;
2108 gpmc->gpio_chip.label = DEVICE_NAME;
2109 gpmc->gpio_chip.ngpio = gpmc_nr_waitpins;
2110 gpmc->gpio_chip.get_direction = gpmc_gpio_get_direction;
2111 gpmc->gpio_chip.direction_input = gpmc_gpio_direction_input;
2112 gpmc->gpio_chip.direction_output = gpmc_gpio_direction_output;
2113 gpmc->gpio_chip.set = gpmc_gpio_set;
2114 gpmc->gpio_chip.get = gpmc_gpio_get;
2115 gpmc->gpio_chip.base = -1;
2116
2117 ret = gpiochip_add(&gpmc->gpio_chip);
2118 if (ret < 0) {
2119 dev_err(gpmc->dev, "could not register gpio chip: %d\n", ret);
2120 return ret;
2121 }
2122
2123 return 0;
2124}
2125
2126static void gpmc_gpio_exit(struct gpmc_device *gpmc)
2127{
2128 gpiochip_remove(&gpmc->gpio_chip);
2129}
2130
2067static int gpmc_probe_dt(struct platform_device *pdev) 2131static int gpmc_probe_dt(struct platform_device *pdev)
2068{ 2132{
2069 int ret; 2133 int ret;
2070 struct device_node *child;
2071 const struct of_device_id *of_id = 2134 const struct of_device_id *of_id =
2072 of_match_device(gpmc_dt_ids, &pdev->dev); 2135 of_match_device(gpmc_dt_ids, &pdev->dev);
2073 2136
@@ -2095,6 +2158,14 @@ static int gpmc_probe_dt(struct platform_device *pdev)
2095 return ret; 2158 return ret;
2096 } 2159 }
2097 2160
2161 return 0;
2162}
2163
2164static int gpmc_probe_dt_children(struct platform_device *pdev)
2165{
2166 int ret;
2167 struct device_node *child;
2168
2098 for_each_available_child_of_node(pdev->dev.of_node, child) { 2169 for_each_available_child_of_node(pdev->dev.of_node, child) {
2099 2170
2100 if (!child->name) 2171 if (!child->name)
@@ -2104,6 +2175,9 @@ static int gpmc_probe_dt(struct platform_device *pdev)
2104 ret = gpmc_probe_onenand_child(pdev, child); 2175 ret = gpmc_probe_onenand_child(pdev, child);
2105 else 2176 else
2106 ret = gpmc_probe_generic_child(pdev, child); 2177 ret = gpmc_probe_generic_child(pdev, child);
2178
2179 if (ret)
2180 return ret;
2107 } 2181 }
2108 2182
2109 return 0; 2183 return 0;
@@ -2113,6 +2187,11 @@ static int gpmc_probe_dt(struct platform_device *pdev)
2113{ 2187{
2114 return 0; 2188 return 0;
2115} 2189}
2190
2191static int gpmc_probe_dt_children(struct platform_device *pdev)
2192{
2193 return 0;
2194}
2116#endif 2195#endif
2117 2196
2118static int gpmc_probe(struct platform_device *pdev) 2197static int gpmc_probe(struct platform_device *pdev)
@@ -2159,6 +2238,15 @@ static int gpmc_probe(struct platform_device *pdev)
2159 return -EINVAL; 2238 return -EINVAL;
2160 } 2239 }
2161 2240
2241 if (pdev->dev.of_node) {
2242 rc = gpmc_probe_dt(pdev);
2243 if (rc)
2244 return rc;
2245 } else {
2246 gpmc_cs_num = GPMC_CS_NUM;
2247 gpmc_nr_waitpins = GPMC_NR_WAITPINS;
2248 }
2249
2162 pm_runtime_enable(&pdev->dev); 2250 pm_runtime_enable(&pdev->dev);
2163 pm_runtime_get_sync(&pdev->dev); 2251 pm_runtime_get_sync(&pdev->dev);
2164 2252
@@ -2184,29 +2272,33 @@ static int gpmc_probe(struct platform_device *pdev)
2184 GPMC_REVISION_MINOR(l)); 2272 GPMC_REVISION_MINOR(l));
2185 2273
2186 gpmc_mem_init(); 2274 gpmc_mem_init();
2275 rc = gpmc_gpio_init(gpmc);
2276 if (rc)
2277 goto gpio_init_failed;
2187 2278
2188 rc = gpmc_setup_irq(gpmc); 2279 rc = gpmc_setup_irq(gpmc);
2189 if (rc) { 2280 if (rc) {
2190 dev_err(gpmc->dev, "gpmc_setup_irq failed\n"); 2281 dev_err(gpmc->dev, "gpmc_setup_irq failed\n");
2191 goto fail; 2282 goto setup_irq_failed;
2192 } 2283 }
2193 2284
2194 if (!pdev->dev.of_node) { 2285 rc = gpmc_probe_dt_children(pdev);
2195 gpmc_cs_num = GPMC_CS_NUM;
2196 gpmc_nr_waitpins = GPMC_NR_WAITPINS;
2197 }
2198
2199 rc = gpmc_probe_dt(pdev);
2200 if (rc < 0) { 2286 if (rc < 0) {
2201 dev_err(gpmc->dev, "failed to probe DT parameters\n"); 2287 dev_err(gpmc->dev, "failed to probe DT children\n");
2202 gpmc_free_irq(gpmc); 2288 goto dt_children_failed;
2203 goto fail;
2204 } 2289 }
2205 2290
2206 return 0; 2291 return 0;
2207 2292
2208fail: 2293dt_children_failed:
2294 gpmc_free_irq(gpmc);
2295setup_irq_failed:
2296 gpmc_gpio_exit(gpmc);
2297gpio_init_failed:
2298 gpmc_mem_exit();
2209 pm_runtime_put_sync(&pdev->dev); 2299 pm_runtime_put_sync(&pdev->dev);
2300 pm_runtime_disable(&pdev->dev);
2301
2210 return rc; 2302 return rc;
2211} 2303}
2212 2304
@@ -2215,6 +2307,7 @@ static int gpmc_remove(struct platform_device *pdev)
2215 struct gpmc_device *gpmc = platform_get_drvdata(pdev); 2307 struct gpmc_device *gpmc = platform_get_drvdata(pdev);
2216 2308
2217 gpmc_free_irq(gpmc); 2309 gpmc_free_irq(gpmc);
2310 gpmc_gpio_exit(gpmc);
2218 gpmc_mem_exit(); 2311 gpmc_mem_exit();
2219 pm_runtime_put_sync(&pdev->dev); 2312 pm_runtime_put_sync(&pdev->dev);
2220 pm_runtime_disable(&pdev->dev); 2313 pm_runtime_disable(&pdev->dev);