aboutsummaryrefslogtreecommitdiffstats
path: root/roms/ipxe/src/include/xen/io/xenbus.h
blob: 182aeb9bce6eaa1ee46ff17770a059a3e3237e5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*****************************************************************************
 * xenbus.h
 *
 * Xenbus protocol details.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Copyright (C) 2005 XenSource Ltd.
 */

#ifndef _XEN_PUBLIC_IO_XENBUS_H
#define _XEN_PUBLIC_IO_XENBUS_H

FILE_LICENCE ( MIT );

/*
 * The state of either end of the Xenbus, i.e. the current communication
 * status of initialisation across the bus.  States here imply nothing about
 * the state of the connection between the driver and the kernel's device
 * layers.
 */
enum xenbus_state {
    XenbusStateUnknown       = 0,

    XenbusStateInitialising  = 1,

    /*
     * InitWait: Finished early initialisation but waiting for information
     * from the peer or hotplug scripts.
     */
    XenbusStateInitWait      = 2,

    /*
     * Initialised: Waiting for a connection from the peer.
     */
    XenbusStateInitialised   = 3,

    XenbusStateConnected     = 4,

    /*
     * Closing: The device is being closed due to an error or an unplug event.
     */
    XenbusStateClosing       = 5,

    XenbusStateClosed        = 6,

    /*
     * Reconfiguring: The device is being reconfigured.
     */
    XenbusStateReconfiguring = 7,

    XenbusStateReconfigured  = 8
};
typedef enum xenbus_state XenbusState;

#endif /* _XEN_PUBLIC_IO_XENBUS_H */

/*
 * Local variables:
 * mode: C
 * c-file-style: "BSD"
 * c-basic-offset: 4
 * tab-width: 4
 * indent-tabs-mode: nil
 * End:
 */
"cpf"><linux/init.h> #include <linux/mutex.h> #include <linux/spi/spi.h> #include <linux/spi/mc33880.h> #include <linux/gpio.h> #include <linux/slab.h> #define DRIVER_NAME "mc33880" /* * Pin configurations, see MAX7301 datasheet page 6 */ #define PIN_CONFIG_MASK 0x03 #define PIN_CONFIG_IN_PULLUP 0x03 #define PIN_CONFIG_IN_WO_PULLUP 0x02 #define PIN_CONFIG_OUT 0x01 #define PIN_NUMBER 8 /* * Some registers must be read back to modify. * To save time we cache them here in memory */ struct mc33880 { struct mutex lock; /* protect from simultaneous accesses */ u8 port_config; struct gpio_chip chip; struct spi_device *spi; }; static int mc33880_write_config(struct mc33880 *mc) { return spi_write(mc->spi, &mc->port_config, sizeof(mc->port_config)); } static int __mc33880_set(struct mc33880 *mc, unsigned offset, int value) { if (value) mc->port_config |= 1 << offset; else mc->port_config &= ~(1 << offset); return mc33880_write_config(mc); } static void mc33880_set(struct gpio_chip *chip, unsigned offset, int value) { struct mc33880 *mc = container_of(chip, struct mc33880, chip); mutex_lock(&mc->lock); __mc33880_set(mc, offset, value); mutex_unlock(&mc->lock); } static int __devinit mc33880_probe(struct spi_device *spi) { struct mc33880 *mc; struct mc33880_platform_data *pdata; int ret; pdata = spi->dev.platform_data; if (!pdata || !pdata->base) { dev_dbg(&spi->dev, "incorrect or missing platform data\n"); return -EINVAL; } /* * bits_per_word cannot be configured in platform data */ spi->bits_per_word = 8; ret = spi_setup(spi); if (ret < 0) return ret; mc = kzalloc(sizeof(struct mc33880), GFP_KERNEL); if (!mc) return -ENOMEM; mutex_init(&mc->lock); dev_set_drvdata(&spi->dev, mc); mc->spi = spi; mc->chip.label = DRIVER_NAME, mc->chip.set = mc33880_set; mc->chip.base = pdata->base; mc->chip.ngpio = PIN_NUMBER; mc->chip.can_sleep = 1; mc->chip.dev = &spi->dev; mc->chip.owner = THIS_MODULE; mc->port_config = 0x00; /* write twice, because during initialisation the first setting * is just for testing SPI communication, and the second is the * "real" configuration */ ret = mc33880_write_config(mc); mc->port_config = 0x00; if (!ret) ret = mc33880_write_config(mc); if (ret) { printk(KERN_ERR "Failed writing to " DRIVER_NAME ": %d\n", ret); goto exit_destroy; } ret = gpiochip_add(&mc->chip); if (ret) goto exit_destroy; return ret; exit_destroy: dev_set_drvdata(&spi->dev, NULL); mutex_destroy(&mc->lock); kfree(mc); return ret; } static int __devexit mc33880_remove(struct spi_device *spi) { struct mc33880 *mc; int ret; mc = dev_get_drvdata(&spi->dev); if (mc == NULL) return -ENODEV; dev_set_drvdata(&spi->dev, NULL); ret = gpiochip_remove(&mc->chip); if (!ret) { mutex_destroy(&mc->lock); kfree(mc); } else dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n", ret); return ret; } static struct spi_driver mc33880_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, }, .probe = mc33880_probe, .remove = __devexit_p(mc33880_remove), }; static int __init mc33880_init(void) { return spi_register_driver(&mc33880_driver); } /* register after spi postcore initcall and before * subsys initcalls that may rely on these GPIOs */ subsys_initcall(mc33880_init); static void __exit mc33880_exit(void) { spi_unregister_driver(&mc33880_driver); } module_exit(mc33880_exit); MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>"); MODULE_LICENSE("GPL v2");