1313// the Samsung pinctrl/gpiolib driver. It also includes the implementation of
1414// external gpio and wakeup interrupt support.
1515
16+ #include <linux/clk.h>
1617#include <linux/device.h>
1718#include <linux/interrupt.h>
1819#include <linux/irqdomain.h>
@@ -61,13 +62,21 @@ static void exynos_irq_mask(struct irq_data *irqd)
6162 else
6263 reg_mask = our_chip -> eint_mask + bank -> eint_offset ;
6364
65+ if (clk_enable (bank -> drvdata -> pclk )) {
66+ dev_err (bank -> gpio_chip .parent ,
67+ "unable to enable clock for masking IRQ\n" );
68+ return ;
69+ }
70+
6471 raw_spin_lock_irqsave (& bank -> slock , flags );
6572
6673 mask = readl (bank -> eint_base + reg_mask );
6774 mask |= 1 << irqd -> hwirq ;
6875 writel (mask , bank -> eint_base + reg_mask );
6976
7077 raw_spin_unlock_irqrestore (& bank -> slock , flags );
78+
79+ clk_disable (bank -> drvdata -> pclk );
7180}
7281
7382static void exynos_irq_ack (struct irq_data * irqd )
@@ -82,7 +91,15 @@ static void exynos_irq_ack(struct irq_data *irqd)
8291 else
8392 reg_pend = our_chip -> eint_pend + bank -> eint_offset ;
8493
94+ if (clk_enable (bank -> drvdata -> pclk )) {
95+ dev_err (bank -> gpio_chip .parent ,
96+ "unable to enable clock to ack IRQ\n" );
97+ return ;
98+ }
99+
85100 writel (1 << irqd -> hwirq , bank -> eint_base + reg_pend );
101+
102+ clk_disable (bank -> drvdata -> pclk );
86103}
87104
88105static void exynos_irq_unmask (struct irq_data * irqd )
@@ -110,13 +127,21 @@ static void exynos_irq_unmask(struct irq_data *irqd)
110127 else
111128 reg_mask = our_chip -> eint_mask + bank -> eint_offset ;
112129
130+ if (clk_enable (bank -> drvdata -> pclk )) {
131+ dev_err (bank -> gpio_chip .parent ,
132+ "unable to enable clock for unmasking IRQ\n" );
133+ return ;
134+ }
135+
113136 raw_spin_lock_irqsave (& bank -> slock , flags );
114137
115138 mask = readl (bank -> eint_base + reg_mask );
116139 mask &= ~(1 << irqd -> hwirq );
117140 writel (mask , bank -> eint_base + reg_mask );
118141
119142 raw_spin_unlock_irqrestore (& bank -> slock , flags );
143+
144+ clk_disable (bank -> drvdata -> pclk );
120145}
121146
122147static int exynos_irq_set_type (struct irq_data * irqd , unsigned int type )
@@ -127,6 +152,7 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
127152 unsigned int shift = EXYNOS_EINT_CON_LEN * irqd -> hwirq ;
128153 unsigned int con , trig_type ;
129154 unsigned long reg_con ;
155+ int ret ;
130156
131157 switch (type ) {
132158 case IRQ_TYPE_EDGE_RISING :
@@ -159,11 +185,20 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
159185 else
160186 reg_con = our_chip -> eint_con + bank -> eint_offset ;
161187
188+ ret = clk_enable (bank -> drvdata -> pclk );
189+ if (ret ) {
190+ dev_err (bank -> gpio_chip .parent ,
191+ "unable to enable clock for configuring IRQ type\n" );
192+ return ret ;
193+ }
194+
162195 con = readl (bank -> eint_base + reg_con );
163196 con &= ~(EXYNOS_EINT_CON_MASK << shift );
164197 con |= trig_type << shift ;
165198 writel (con , bank -> eint_base + reg_con );
166199
200+ clk_disable (bank -> drvdata -> pclk );
201+
167202 return 0 ;
168203}
169204
@@ -200,6 +235,14 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
200235 shift = irqd -> hwirq * bank_type -> fld_width [PINCFG_TYPE_FUNC ];
201236 mask = (1 << bank_type -> fld_width [PINCFG_TYPE_FUNC ]) - 1 ;
202237
238+ ret = clk_enable (bank -> drvdata -> pclk );
239+ if (ret ) {
240+ dev_err (bank -> gpio_chip .parent ,
241+ "unable to enable clock for configuring pin %s-%lu\n" ,
242+ bank -> name , irqd -> hwirq );
243+ return ret ;
244+ }
245+
203246 raw_spin_lock_irqsave (& bank -> slock , flags );
204247
205248 con = readl (bank -> pctl_base + reg_con );
@@ -209,6 +252,8 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
209252
210253 raw_spin_unlock_irqrestore (& bank -> slock , flags );
211254
255+ clk_disable (bank -> drvdata -> pclk );
256+
212257 return 0 ;
213258}
214259
@@ -223,6 +268,13 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
223268 shift = irqd -> hwirq * bank_type -> fld_width [PINCFG_TYPE_FUNC ];
224269 mask = (1 << bank_type -> fld_width [PINCFG_TYPE_FUNC ]) - 1 ;
225270
271+ if (clk_enable (bank -> drvdata -> pclk )) {
272+ dev_err (bank -> gpio_chip .parent ,
273+ "unable to enable clock for deconfiguring pin %s-%lu\n" ,
274+ bank -> name , irqd -> hwirq );
275+ return ;
276+ }
277+
226278 raw_spin_lock_irqsave (& bank -> slock , flags );
227279
228280 con = readl (bank -> pctl_base + reg_con );
@@ -232,6 +284,8 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
232284
233285 raw_spin_unlock_irqrestore (& bank -> slock , flags );
234286
287+ clk_disable (bank -> drvdata -> pclk );
288+
235289 gpiochip_unlock_as_irq (& bank -> gpio_chip , irqd -> hwirq );
236290}
237291
@@ -281,10 +335,19 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
281335 unsigned int svc , group , pin ;
282336 int ret ;
283337
338+ if (clk_enable (bank -> drvdata -> pclk )) {
339+ dev_err (bank -> gpio_chip .parent ,
340+ "unable to enable clock for handling IRQ\n" );
341+ return IRQ_NONE ;
342+ }
343+
284344 if (bank -> eint_con_offset )
285345 svc = readl (bank -> eint_base + EXYNOSAUTO_SVC_OFFSET );
286346 else
287347 svc = readl (bank -> eint_base + EXYNOS_SVC_OFFSET );
348+
349+ clk_disable (bank -> drvdata -> pclk );
350+
288351 group = EXYNOS_SVC_GROUP (svc );
289352 pin = svc & EXYNOS_SVC_NUM_MASK ;
290353
@@ -563,6 +626,20 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
563626
564627 chained_irq_enter (chip , desc );
565628
629+ /*
630+ * just enable the clock once here, to avoid an enable/disable dance for
631+ * each bank.
632+ */
633+ if (eintd -> nr_banks ) {
634+ struct samsung_pin_bank * b = eintd -> banks [0 ];
635+
636+ if (clk_enable (b -> drvdata -> pclk )) {
637+ dev_err (b -> gpio_chip .parent ,
638+ "unable to enable clock for pending IRQs\n" );
639+ return ;
640+ }
641+ }
642+
566643 for (i = 0 ; i < eintd -> nr_banks ; ++ i ) {
567644 struct samsung_pin_bank * b = eintd -> banks [i ];
568645 pend = readl (b -> eint_base + b -> irq_chip -> eint_pend
@@ -572,6 +649,9 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
572649 exynos_irq_demux_eint (pend & ~mask , b -> irq_domain );
573650 }
574651
652+ if (eintd -> nr_banks )
653+ clk_disable (eintd -> banks [0 ]-> drvdata -> pclk );
654+
575655 chained_irq_exit (chip , desc );
576656}
577657
@@ -695,6 +775,12 @@ static void exynos_pinctrl_suspend_bank(
695775 struct exynos_eint_gpio_save * save = bank -> soc_priv ;
696776 const void __iomem * regs = bank -> eint_base ;
697777
778+ if (clk_enable (bank -> drvdata -> pclk )) {
779+ dev_err (bank -> gpio_chip .parent ,
780+ "unable to enable clock for saving state\n" );
781+ return ;
782+ }
783+
698784 save -> eint_con = readl (regs + EXYNOS_GPIO_ECON_OFFSET
699785 + bank -> eint_offset );
700786 save -> eint_fltcon0 = readl (regs + EXYNOS_GPIO_EFLTCON_OFFSET
@@ -704,6 +790,8 @@ static void exynos_pinctrl_suspend_bank(
704790 save -> eint_mask = readl (regs + bank -> irq_chip -> eint_mask
705791 + bank -> eint_offset );
706792
793+ clk_disable (bank -> drvdata -> pclk );
794+
707795 pr_debug ("%s: save con %#010x\n" , bank -> name , save -> eint_con );
708796 pr_debug ("%s: save fltcon0 %#010x\n" , bank -> name , save -> eint_fltcon0 );
709797 pr_debug ("%s: save fltcon1 %#010x\n" , bank -> name , save -> eint_fltcon1 );
@@ -716,9 +804,17 @@ static void exynosauto_pinctrl_suspend_bank(struct samsung_pinctrl_drv_data *drv
716804 struct exynos_eint_gpio_save * save = bank -> soc_priv ;
717805 const void __iomem * regs = bank -> eint_base ;
718806
807+ if (clk_enable (bank -> drvdata -> pclk )) {
808+ dev_err (bank -> gpio_chip .parent ,
809+ "unable to enable clock for saving state\n" );
810+ return ;
811+ }
812+
719813 save -> eint_con = readl (regs + bank -> pctl_offset + bank -> eint_con_offset );
720814 save -> eint_mask = readl (regs + bank -> pctl_offset + bank -> eint_mask_offset );
721815
816+ clk_disable (bank -> drvdata -> pclk );
817+
722818 pr_debug ("%s: save con %#010x\n" , bank -> name , save -> eint_con );
723819 pr_debug ("%s: save mask %#010x\n" , bank -> name , save -> eint_mask );
724820}
@@ -753,6 +849,12 @@ static void exynos_pinctrl_resume_bank(
753849 struct exynos_eint_gpio_save * save = bank -> soc_priv ;
754850 void __iomem * regs = bank -> eint_base ;
755851
852+ if (clk_enable (bank -> drvdata -> pclk )) {
853+ dev_err (bank -> gpio_chip .parent ,
854+ "unable to enable clock for restoring state\n" );
855+ return ;
856+ }
857+
756858 pr_debug ("%s: con %#010x => %#010x\n" , bank -> name ,
757859 readl (regs + EXYNOS_GPIO_ECON_OFFSET
758860 + bank -> eint_offset ), save -> eint_con );
@@ -774,6 +876,8 @@ static void exynos_pinctrl_resume_bank(
774876 + 2 * bank -> eint_offset + 4 );
775877 writel (save -> eint_mask , regs + bank -> irq_chip -> eint_mask
776878 + bank -> eint_offset );
879+
880+ clk_disable (bank -> drvdata -> pclk );
777881}
778882
779883static void exynosauto_pinctrl_resume_bank (struct samsung_pinctrl_drv_data * drvdata ,
@@ -782,13 +886,21 @@ static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvd
782886 struct exynos_eint_gpio_save * save = bank -> soc_priv ;
783887 void __iomem * regs = bank -> eint_base ;
784888
889+ if (clk_enable (bank -> drvdata -> pclk )) {
890+ dev_err (bank -> gpio_chip .parent ,
891+ "unable to enable clock for restoring state\n" );
892+ return ;
893+ }
894+
785895 pr_debug ("%s: con %#010x => %#010x\n" , bank -> name ,
786896 readl (regs + bank -> pctl_offset + bank -> eint_con_offset ), save -> eint_con );
787897 pr_debug ("%s: mask %#010x => %#010x\n" , bank -> name ,
788898 readl (regs + bank -> pctl_offset + bank -> eint_mask_offset ), save -> eint_mask );
789899
790900 writel (save -> eint_con , regs + bank -> pctl_offset + bank -> eint_con_offset );
791901 writel (save -> eint_mask , regs + bank -> pctl_offset + bank -> eint_mask_offset );
902+
903+ clk_disable (bank -> drvdata -> pclk );
792904}
793905
794906void exynos_pinctrl_resume (struct samsung_pinctrl_drv_data * drvdata )
0 commit comments