@@ -38,7 +38,7 @@ struct exynos_irq_chip {
3838 u32 eint_con ;
3939 u32 eint_mask ;
4040 u32 eint_pend ;
41- u32 eint_wake_mask_value ;
41+ u32 * eint_wake_mask_value ;
4242 u32 eint_wake_mask_reg ;
4343 void (* set_eint_wakeup_mask )(struct samsung_pinctrl_drv_data * drvdata ,
4444 struct exynos_irq_chip * irq_chip );
@@ -207,7 +207,7 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
207207/*
208208 * irq_chip for gpio interrupts.
209209 */
210- static struct exynos_irq_chip exynos_gpio_irq_chip = {
210+ static const struct exynos_irq_chip exynos_gpio_irq_chip __initconst = {
211211 .chip = {
212212 .name = "exynos_gpio_irq_chip" ,
213213 .irq_unmask = exynos_irq_unmask ,
@@ -274,7 +274,7 @@ struct exynos_eint_gpio_save {
274274 * exynos_eint_gpio_init() - setup handling of external gpio interrupts.
275275 * @d: driver data of samsung pinctrl driver.
276276 */
277- int exynos_eint_gpio_init (struct samsung_pinctrl_drv_data * d )
277+ __init int exynos_eint_gpio_init (struct samsung_pinctrl_drv_data * d )
278278{
279279 struct samsung_pin_bank * bank ;
280280 struct device * dev = d -> dev ;
@@ -297,6 +297,15 @@ int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
297297 for (i = 0 ; i < d -> nr_banks ; ++ i , ++ bank ) {
298298 if (bank -> eint_type != EINT_TYPE_GPIO )
299299 continue ;
300+
301+ bank -> irq_chip = devm_kmemdup (dev , & exynos_gpio_irq_chip ,
302+ sizeof (* bank -> irq_chip ), GFP_KERNEL );
303+ if (!bank -> irq_chip ) {
304+ ret = - ENOMEM ;
305+ goto err_domains ;
306+ }
307+ bank -> irq_chip -> chip .name = bank -> name ;
308+
300309 bank -> irq_domain = irq_domain_add_linear (bank -> of_node ,
301310 bank -> nr_pins , & exynos_eint_irqd_ops , bank );
302311 if (!bank -> irq_domain ) {
@@ -313,7 +322,6 @@ int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
313322 goto err_domains ;
314323 }
315324
316- bank -> irq_chip = & exynos_gpio_irq_chip ;
317325 }
318326
319327 return 0 ;
@@ -338,9 +346,9 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
338346 pr_info ("wake %s for irq %d\n" , on ? "enabled" : "disabled" , irqd -> irq );
339347
340348 if (!on )
341- our_chip -> eint_wake_mask_value |= bit ;
349+ * our_chip -> eint_wake_mask_value |= bit ;
342350 else
343- our_chip -> eint_wake_mask_value &= ~bit ;
351+ * our_chip -> eint_wake_mask_value &= ~bit ;
344352
345353 return 0 ;
346354}
@@ -360,10 +368,10 @@ exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
360368 pmu_regs = drvdata -> retention_ctrl -> priv ;
361369 dev_info (drvdata -> dev ,
362370 "Setting external wakeup interrupt mask: 0x%x\n" ,
363- irq_chip -> eint_wake_mask_value );
371+ * irq_chip -> eint_wake_mask_value );
364372
365373 regmap_write (pmu_regs , irq_chip -> eint_wake_mask_reg ,
366- irq_chip -> eint_wake_mask_value );
374+ * irq_chip -> eint_wake_mask_value );
367375}
368376
369377static void
@@ -382,10 +390,11 @@ s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
382390
383391 clk_base = (void __iomem * ) drvdata -> retention_ctrl -> priv ;
384392
385- __raw_writel (irq_chip -> eint_wake_mask_value ,
393+ __raw_writel (* irq_chip -> eint_wake_mask_value ,
386394 clk_base + irq_chip -> eint_wake_mask_reg );
387395}
388396
397+ static u32 eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED ;
389398/*
390399 * irq_chip for wakeup interrupts
391400 */
@@ -403,7 +412,7 @@ static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst = {
403412 .eint_con = EXYNOS_WKUP_ECON_OFFSET ,
404413 .eint_mask = EXYNOS_WKUP_EMASK_OFFSET ,
405414 .eint_pend = EXYNOS_WKUP_EPEND_OFFSET ,
406- .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED ,
415+ .eint_wake_mask_value = & eint_wake_mask_value ,
407416 /* Only differences with exynos4210_wkup_irq_chip: */
408417 .eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK ,
409418 .set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask ,
@@ -423,7 +432,7 @@ static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
423432 .eint_con = EXYNOS_WKUP_ECON_OFFSET ,
424433 .eint_mask = EXYNOS_WKUP_EMASK_OFFSET ,
425434 .eint_pend = EXYNOS_WKUP_EPEND_OFFSET ,
426- .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED ,
435+ .eint_wake_mask_value = & eint_wake_mask_value ,
427436 .eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK ,
428437 .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask ,
429438};
@@ -442,7 +451,7 @@ static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
442451 .eint_con = EXYNOS7_WKUP_ECON_OFFSET ,
443452 .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET ,
444453 .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET ,
445- .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED ,
454+ .eint_wake_mask_value = & eint_wake_mask_value ,
446455 .eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK ,
447456 .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask ,
448457};
@@ -513,15 +522,15 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
513522 * exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
514523 * @d: driver data of samsung pinctrl driver.
515524 */
516- int exynos_eint_wkup_init (struct samsung_pinctrl_drv_data * d )
525+ __init int exynos_eint_wkup_init (struct samsung_pinctrl_drv_data * d )
517526{
518527 struct device * dev = d -> dev ;
519528 struct device_node * wkup_np = NULL ;
520529 struct device_node * np ;
521530 struct samsung_pin_bank * bank ;
522531 struct exynos_weint_data * weint_data ;
523532 struct exynos_muxed_weint_data * muxed_data ;
524- struct exynos_irq_chip * irq_chip ;
533+ const struct exynos_irq_chip * irq_chip ;
525534 unsigned int muxed_banks = 0 ;
526535 unsigned int i ;
527536 int idx , irq ;
@@ -531,12 +540,7 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
531540
532541 match = of_match_node (exynos_wkup_irq_ids , np );
533542 if (match ) {
534- irq_chip = kmemdup (match -> data ,
535- sizeof (* irq_chip ), GFP_KERNEL );
536- if (!irq_chip ) {
537- of_node_put (np );
538- return - ENOMEM ;
539- }
543+ irq_chip = match -> data ;
540544 wkup_np = np ;
541545 break ;
542546 }
@@ -549,6 +553,14 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
549553 if (bank -> eint_type != EINT_TYPE_WKUP )
550554 continue ;
551555
556+ bank -> irq_chip = devm_kmemdup (dev , irq_chip , sizeof (* irq_chip ),
557+ GFP_KERNEL );
558+ if (!bank -> irq_chip ) {
559+ of_node_put (wkup_np );
560+ return - ENOMEM ;
561+ }
562+ bank -> irq_chip -> chip .name = bank -> name ;
563+
552564 bank -> irq_domain = irq_domain_add_linear (bank -> of_node ,
553565 bank -> nr_pins , & exynos_eint_irqd_ops , bank );
554566 if (!bank -> irq_domain ) {
@@ -557,8 +569,6 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
557569 return - ENXIO ;
558570 }
559571
560- bank -> irq_chip = irq_chip ;
561-
562572 if (!of_find_property (bank -> of_node , "interrupts" , NULL )) {
563573 bank -> eint_type = EINT_TYPE_WKUP_MUX ;
564574 ++ muxed_banks ;
@@ -657,10 +667,6 @@ void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
657667 irq_chip = bank -> irq_chip ;
658668 irq_chip -> set_eint_wakeup_mask (drvdata ,
659669 irq_chip );
660- } else if (bank -> irq_chip != irq_chip ) {
661- dev_warn (drvdata -> dev ,
662- "More than one external wakeup interrupt chip configured (bank: %s). This is not supported by hardware nor by driver.\n" ,
663- bank -> name );
664670 }
665671 }
666672 }
0 commit comments